From 04d0cba0ecacdb348ab1d33bbfd3b116946e3780 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Mon, 18 Jun 2018 21:31:46 +0000 Subject: [PATCH] Initial support for 4.4 LTS with ARM IPROC support. --- .../4.4-lts/configs/arm-iproc-all/.gitignore | 3 + .../4.4-lts/configs/arm-iproc-all/Makefile | 41 + .../arm-iproc-all/arm-iproc-all.config | 3029 + packages/base/any/kernels/4.4-lts/kconfig.mk | 26 + .../patches/kernel-4.4-brcm-iproc.patch | 75281 ++++++++++++++++ .../base/any/kernels/4.4-lts/patches/series | 1 + 6 files changed, 78381 insertions(+) create mode 100644 packages/base/any/kernels/4.4-lts/configs/arm-iproc-all/.gitignore create mode 100644 packages/base/any/kernels/4.4-lts/configs/arm-iproc-all/Makefile create mode 100644 packages/base/any/kernels/4.4-lts/configs/arm-iproc-all/arm-iproc-all.config create mode 100644 packages/base/any/kernels/4.4-lts/kconfig.mk create mode 100644 packages/base/any/kernels/4.4-lts/patches/kernel-4.4-brcm-iproc.patch create mode 100644 packages/base/any/kernels/4.4-lts/patches/series diff --git a/packages/base/any/kernels/4.4-lts/configs/arm-iproc-all/.gitignore b/packages/base/any/kernels/4.4-lts/configs/arm-iproc-all/.gitignore new file mode 100644 index 00000000..5540b78d --- /dev/null +++ b/packages/base/any/kernels/4.4-lts/configs/arm-iproc-all/.gitignore @@ -0,0 +1,3 @@ +kernel-* +linux-* +lib/ diff --git a/packages/base/any/kernels/4.4-lts/configs/arm-iproc-all/Makefile b/packages/base/any/kernels/4.4-lts/configs/arm-iproc-all/Makefile new file mode 100644 index 00000000..b3fcbd82 --- /dev/null +++ b/packages/base/any/kernels/4.4-lts/configs/arm-iproc-all/Makefile @@ -0,0 +1,41 @@ +############################################################ +# +# +# Copyright 2015 Big Switch Networks, Inc. +# +# Licensed under the Eclipse Public License, Version 1.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.eclipse.org/legal/epl-v10.html +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +# either express or implied. See the License for the specific +# language governing permissions and limitations under the +# License. +# +# +############################################################ + +THIS_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) +include $(ONL)/make/config.mk + +ifndef K_TARGET_DIR +K_TARGET_DIR := $(THIS_DIR) +endif + +K_PATCH_DIR := $(THIS_DIR)/patches + +include ../../kconfig.mk +K_CONFIG := arm-iproc-all.config +K_BUILD_TARGET := Image +K_COPY_SRC := arch/arm/boot/Image +K_COPY_GZIP := 1 +ifndef K_COPY_DST +K_COPY_DST := kernel-4.4-lts-arm-iproc-all.bin.gz +endif + +export ARCH=arm +include $(ONL)/make/kbuild.mk diff --git a/packages/base/any/kernels/4.4-lts/configs/arm-iproc-all/arm-iproc-all.config b/packages/base/any/kernels/4.4-lts/configs/arm-iproc-all/arm-iproc-all.config new file mode 100644 index 00000000..b1a38f03 --- /dev/null +++ b/packages/base/any/kernels/4.4-lts/configs/arm-iproc-all/arm-iproc-all.config @@ -0,0 +1,3029 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux/arm 4.4.39 Kernel Configuration +# +CONFIG_ARM=y +CONFIG_ARM_HAS_SG_CHAIN=y +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_NEED_DMA_MAP_STATE=y +CONFIG_ARCH_SUPPORTS_UPROBES=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_ARM_PATCH_PHYS_VIRT=y +CONFIG_GENERIC_BUG=y +CONFIG_PGTABLE_LEVELS=2 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_IRQ_WORK=y +CONFIG_BUILDTIME_EXTABLE_SORT=y + +# +# General setup +# +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_CROSS_COMPILE="arm-linux-gnueabi-" +# CONFIG_COMPILE_TEST is not set +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +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 is not set +CONFIG_CROSS_MEMORY_ATTACH=y +# CONFIG_FHANDLE is not set +CONFIG_USELIB=y +# 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_HARDIRQS_SW_RESEND=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_GENERIC_MSI_IRQ=y +CONFIG_HANDLE_DOMAIN_IRQ=y +# CONFIG_IRQ_DOMAIN_DEBUG is not set +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_SPARSE_IRQ=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 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 + +# +# RCU Subsystem +# +CONFIG_PREEMPT_RCU=y +# CONFIG_RCU_EXPERT is not set +CONFIG_SRCU=y +# CONFIG_TASKS_RCU is not set +CONFIG_RCU_STALL_COMMON=y +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_RCU_EXPEDITE_BOOT is not set +CONFIG_BUILD_BIN2C=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 +CONFIG_GENERIC_SCHED_CLOCK=y +# CONFIG_CGROUPS is not set +# CONFIG_CHECKPOINT_RESTORE is not set +# CONFIG_NAMESPACES is not set +# CONFIG_SCHED_AUTOGROUP is not set +# CONFIG_SYSFS_DEPRECATED is not set +# CONFIG_RELAY is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=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=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +# CONFIG_ELF_CORE is not set +# CONFIG_BASE_FULL is not set +CONFIG_FUTEX=y +# CONFIG_EPOLL is not set +# CONFIG_SIGNALFD is not set +# CONFIG_TIMERFD is not set +# CONFIG_EVENTFD is not set +# CONFIG_BPF_SYSCALL is not set +# CONFIG_SHMEM is not set +# CONFIG_AIO is not set +CONFIG_ADVISE_SYSCALLS=y +# CONFIG_USERFAULTFD is not set +CONFIG_PCI_QUIRKS=y +CONFIG_MEMBARRIER=y +CONFIG_EMBEDDED=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y + +# +# Kernel Performance Events And Counters +# +# CONFIG_PERF_EVENTS is not set +CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_SLUB_DEBUG is not set +# CONFIG_COMPAT_BRK is not set +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +CONFIG_SLUB_CPU_PARTIAL=y +# CONFIG_SYSTEM_DATA_VERIFICATION is not set +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +# CONFIG_JUMP_LABEL is not set +# CONFIG_UPROBES is not set +# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_ARCH_USE_BUILTIN_BSWAP=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_OPTPROBES=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=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_HAVE_CC_STACKPROTECTOR=y +# CONFIG_CC_STACKPROTECTOR is not set +CONFIG_CC_STACKPROTECTOR_NONE=y +# CONFIG_CC_STACKPROTECTOR_REGULAR is not set +# CONFIG_CC_STACKPROTECTOR_STRONG is not set +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_CLONE_BACKWARDS=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_OLD_SIGACTION=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=1 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD 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_BLOCK=y +CONFIG_LBDAF=y +CONFIG_BLK_DEV_BSG=y +# CONFIG_BLK_DEV_BSGLIB is not set +# CONFIG_BLK_DEV_INTEGRITY is not set +# CONFIG_BLK_CMDLINE_PARSER 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 is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_UNINLINE_SPIN_UNLOCK=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 + +# +# System Type +# +CONFIG_MMU=y +CONFIG_ARCH_MULTIPLATFORM=y +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_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_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP 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_S3C64XX 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_MULTI_CPU_AUTO is not set +# CONFIG_ARCH_VIRT is not set +# CONFIG_ARCH_MVEBU is not set +# CONFIG_ARCH_ALPINE 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_HIGHBANK is not set +# CONFIG_ARCH_HISI is not set +CONFIG_ARCH_XGS_IPROC=y + +# +# XGS iProc SoC based Machine types +# +CONFIG_MACH_HX4=y +# CONFIG_MACH_HR2 is not set +# CONFIG_MACH_KT2 is not set +# CONFIG_MACH_GH is not set +# CONFIG_MACH_SB2 is not set +# CONFIG_MACH_HR3 is not set +# CONFIG_MACH_GH2 is not set +# CONFIG_MACH_IPROC_EMULATION is not set +# CONFIG_ARCH_KEYSTONE is not set +# CONFIG_ARCH_MESON is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_MEDIATEK 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_QCOM is not set +# CONFIG_ARCH_ROCKCHIP is not set +# CONFIG_ARCH_SOCFPGA is not set +# CONFIG_PLAT_SPEAR is not set +# CONFIG_ARCH_STI is not set +# CONFIG_ARCH_S5PV210 is not set +# CONFIG_ARCH_EXYNOS is not set +# CONFIG_ARCH_SHMOBILE_MULTI is not set +# CONFIG_ARCH_SUNXI is not set +# CONFIG_ARCH_SIRF 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_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_ARCH_PHYS_ADDR_T_64BIT is not set +CONFIG_ARM_THUMB=y +# CONFIG_ARM_THUMBEE is not set +CONFIG_ARM_VIRT_EXT=y +CONFIG_SWP_EMULATE=y +# CONFIG_CPU_BIG_ENDIAN is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_KUSER_HELPERS=y +# CONFIG_VDSO is not set +CONFIG_OUTER_CACHE=y +CONFIG_OUTER_CACHE_SYNC=y +CONFIG_MIGHT_HAVE_CACHE_L2X0=y +CONFIG_CACHE_L2X0=y +# CONFIG_PL310_ERRATA_588369 is not set +# CONFIG_PL310_ERRATA_727915 is not set +# CONFIG_PL310_ERRATA_753970 is not set +# CONFIG_PL310_ERRATA_769419 is not set +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_ARCH_SUPPORTS_BIG_ENDIAN=y +# CONFIG_ARM_KERNMEM_PERMS is not set +CONFIG_MULTI_IRQ_HANDLER=y +# CONFIG_ARM_ERRATA_430973 is not set +# CONFIG_ARM_ERRATA_643719 is not set +# CONFIG_ARM_ERRATA_720789 is not set +CONFIG_ARM_ERRATA_754322=y +# CONFIG_ARM_ERRATA_754327 is not set +CONFIG_ARM_ERRATA_764369=y +CONFIG_ARM_ERRATA_775420=y +# CONFIG_ARM_ERRATA_798181 is not set +# CONFIG_ARM_ERRATA_773022 is not set + +# +# Bus support +# +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_DOMAINS_GENERIC=y +CONFIG_PCI_SYSCALL=y +CONFIG_PCI_MSI=y +# CONFIG_PCI_DEBUG is not set +# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set +# CONFIG_PCI_STUB is not set +# CONFIG_PCI_IOV is not set +# CONFIG_PCI_PRI is not set +# CONFIG_PCI_PASID is not set + +# +# PCI host controller drivers +# +# CONFIG_PCI_HOST_GENERIC is not set +# CONFIG_PCI_LAYERSCAPE is not set +CONFIG_PCIE_XGS_IPROC=y +# CONFIG_PCIE_IPROC is not set +# CONFIG_PCIE_ALTERA is not set +# CONFIG_PCIEPORTBUS 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_SCU=y +# CONFIG_HAVE_ARM_ARCH_TIMER is not set +CONFIG_HAVE_ARM_TWD=y +# CONFIG_MCPM is not set +# 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=4 +CONFIG_HOTPLUG_CPU=y +# CONFIG_ARM_PSCI is not set +CONFIG_ARCH_NR_GPIO=0 +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_PREEMPT_COUNT=y +CONFIG_HZ_FIXED=0 +CONFIG_HZ_100=y +# CONFIG_HZ_200 is not set +# CONFIG_HZ_250 is not set +# CONFIG_HZ_300 is not set +# CONFIG_HZ_500 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=100 +# CONFIG_SCHED_HRTICK is not set +# CONFIG_THUMB2_KERNEL is not set +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +CONFIG_HAVE_ARCH_PFN_VALID=y +# CONFIG_HIGHMEM is not set +CONFIG_CPU_SW_DOMAIN_PAN=y +CONFIG_ARCH_WANT_GENERAL_HUGETLB=y +# CONFIG_ARM_MODULE_PLTS is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_NO_BOOTMEM=y +CONFIG_MEMORY_ISOLATION=y +# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_COMPACTION is not set +CONFIG_MIGRATION=y +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +# CONFIG_CLEANCACHE is not set +# CONFIG_FRONTSWAP is not set +CONFIG_CMA=y +CONFIG_CMA_DEBUG=y +# CONFIG_CMA_DEBUGFS is not set +CONFIG_CMA_AREAS=7 +# CONFIG_ZPOOL is not set +# CONFIG_ZBUD is not set +# CONFIG_ZSMALLOC is not set +# CONFIG_IDLE_PAGE_TRACKING is not set +CONFIG_FORCE_MAX_ZONEORDER=11 +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set +# CONFIG_SECCOMP is not set +CONFIG_SWIOTLB=y +CONFIG_IOMMU_HELPER=y +# 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=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +# CONFIG_ARM_APPENDED_DTB is not set +CONFIG_CMDLINE="console=ttyS0,115200n8 maxcpus=2 mem=496M" +CONFIG_CMDLINE_FROM_BOOTLOADER=y +# CONFIG_CMDLINE_EXTEND is not set +# CONFIG_CMDLINE_FORCE is not set +# CONFIG_KEXEC is not set +# CONFIG_CRASH_DUMP is not set +CONFIG_AUTO_ZRELADDR=y + +# +# CPU Power Management +# + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + +# +# CPU Idle +# +# CONFIG_CPU_IDLE is not set +# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_SCRIPT=y +# CONFIG_HAVE_AOUT is not set +# CONFIG_BINFMT_MISC is not set +CONFIG_COREDUMP=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 is not set +# 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_WQ_POWER_EFFICIENT_DEFAULT is not set +CONFIG_CPU_PM=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARM_CPU_SUSPEND=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_NET=y +CONFIG_NET_INGRESS=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_DIAG is not set +CONFIG_UNIX=y +# CONFIG_UNIX_DIAG is not set +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +# CONFIG_IP_FIB_TRIE_STATS is not set +CONFIG_IP_MULTIPLE_TABLES=y +# CONFIG_IP_ROUTE_MULTIPATH is not set +# CONFIG_IP_ROUTE_VERBOSE is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE_DEMUX is not set +CONFIG_NET_IP_TUNNEL=y +# CONFIG_IP_MROUTE is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_NET_UDP_TUNNEL is not set +# CONFIG_NET_FOU is not set +# CONFIG_NET_FOU_IP_TUNNELS is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +CONFIG_INET_TUNNEL=y +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IPV6=y +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_ILA is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +CONFIG_INET6_TUNNEL=y +CONFIG_INET6_XFRM_MODE_TRANSPORT=y +CONFIG_INET6_XFRM_MODE_TUNNEL=y +CONFIG_INET6_XFRM_MODE_BEET=y +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +# CONFIG_IPV6_VTI is not set +CONFIG_IPV6_SIT=y +# CONFIG_IPV6_SIT_6RD is not set +CONFIG_IPV6_NDISC_NODETYPE=y +CONFIG_IPV6_TUNNEL=y +# CONFIG_IPV6_GRE is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_NETWORK_SECMARK is not set +CONFIG_NET_PTP_CLASSIFY=y +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +CONFIG_NETFILTER=y +CONFIG_NETFILTER_DEBUG=y +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_INGRESS=y +CONFIG_NETFILTER_NETLINK=y +# CONFIG_NETFILTER_NETLINK_ACCT is not set +CONFIG_NETFILTER_NETLINK_QUEUE=y +CONFIG_NETFILTER_NETLINK_LOG=y +CONFIG_NF_CONNTRACK=y +CONFIG_NF_CONNTRACK_MARK=y +# CONFIG_NF_CONNTRACK_ZONES is not set +CONFIG_NF_CONNTRACK_PROCFS=y +# CONFIG_NF_CONNTRACK_EVENTS is not set +# CONFIG_NF_CONNTRACK_TIMEOUT is not set +# CONFIG_NF_CONNTRACK_TIMESTAMP is not set +# CONFIG_NF_CT_PROTO_DCCP is not set +# CONFIG_NF_CT_PROTO_SCTP is not set +# CONFIG_NF_CT_PROTO_UDPLITE is not set +# CONFIG_NF_CONNTRACK_AMANDA is not set +CONFIG_NF_CONNTRACK_FTP=y +# CONFIG_NF_CONNTRACK_H323 is not set +# CONFIG_NF_CONNTRACK_IRC is not set +# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set +# CONFIG_NF_CONNTRACK_SNMP is not set +# CONFIG_NF_CONNTRACK_PPTP is not set +# CONFIG_NF_CONNTRACK_SANE is not set +# CONFIG_NF_CONNTRACK_SIP is not set +CONFIG_NF_CONNTRACK_TFTP=y +# CONFIG_NF_CT_NETLINK is not set +# CONFIG_NF_CT_NETLINK_TIMEOUT is not set +# CONFIG_NF_TABLES is not set +CONFIG_NETFILTER_XTABLES=y + +# +# Xtables combined modules +# +CONFIG_NETFILTER_XT_MARK=y +CONFIG_NETFILTER_XT_CONNMARK=y + +# +# Xtables targets +# +# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set +# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set +# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set +CONFIG_NETFILTER_XT_TARGET_CT=y +# CONFIG_NETFILTER_XT_TARGET_DSCP is not set +CONFIG_NETFILTER_XT_TARGET_HL=y +# CONFIG_NETFILTER_XT_TARGET_HMARK is not set +# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set +# CONFIG_NETFILTER_XT_TARGET_LOG is not set +# CONFIG_NETFILTER_XT_TARGET_MARK is not set +# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set +# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set +# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set +# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set +# CONFIG_NETFILTER_XT_TARGET_TEE is not set +# CONFIG_NETFILTER_XT_TARGET_TPROXY is not set +# CONFIG_NETFILTER_XT_TARGET_TRACE is not set +CONFIG_NETFILTER_XT_TARGET_TCPMSS=y +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set + +# +# Xtables matches +# +# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set +# CONFIG_NETFILTER_XT_MATCH_BPF is not set +# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set +# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set +# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set +# CONFIG_NETFILTER_XT_MATCH_CONNLABEL is not set +# CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set +CONFIG_NETFILTER_XT_MATCH_CONNMARK=y +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y +# CONFIG_NETFILTER_XT_MATCH_CPU is not set +# CONFIG_NETFILTER_XT_MATCH_DCCP is not set +# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set +# CONFIG_NETFILTER_XT_MATCH_DSCP is not set +CONFIG_NETFILTER_XT_MATCH_ECN=y +# CONFIG_NETFILTER_XT_MATCH_ESP is not set +# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set +CONFIG_NETFILTER_XT_MATCH_HELPER=y +CONFIG_NETFILTER_XT_MATCH_HL=y +# CONFIG_NETFILTER_XT_MATCH_IPCOMP is not set +# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set +# CONFIG_NETFILTER_XT_MATCH_L2TP is not set +# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set +# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set +# CONFIG_NETFILTER_XT_MATCH_MAC is not set +# CONFIG_NETFILTER_XT_MATCH_MARK is not set +# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set +# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set +# CONFIG_NETFILTER_XT_MATCH_OSF is not set +# CONFIG_NETFILTER_XT_MATCH_OWNER is not set +# CONFIG_NETFILTER_XT_MATCH_POLICY is not set +# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set +# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set +# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set +# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set +# CONFIG_NETFILTER_XT_MATCH_REALM is not set +# CONFIG_NETFILTER_XT_MATCH_RECENT is not set +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set +# CONFIG_NETFILTER_XT_MATCH_SOCKET is not set +CONFIG_NETFILTER_XT_MATCH_STATE=y +# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set +# CONFIG_NETFILTER_XT_MATCH_STRING is not set +CONFIG_NETFILTER_XT_MATCH_TCPMSS=y +# CONFIG_NETFILTER_XT_MATCH_TIME is not set +# CONFIG_NETFILTER_XT_MATCH_U32 is not set +# CONFIG_IP_SET is not set +# CONFIG_IP_VS is not set + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=y +CONFIG_NF_CONNTRACK_IPV4=y +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +# CONFIG_NF_DUP_IPV4 is not set +# CONFIG_NF_LOG_ARP is not set +# CONFIG_NF_LOG_IPV4 is not set +CONFIG_NF_REJECT_IPV4=y +# CONFIG_NF_NAT_IPV4 is not set +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_MATCH_AH=y +CONFIG_IP_NF_MATCH_ECN=y +# CONFIG_IP_NF_MATCH_RPFILTER is not set +CONFIG_IP_NF_MATCH_TTL=y +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +# CONFIG_IP_NF_TARGET_SYNPROXY is not set +# CONFIG_IP_NF_NAT is not set +CONFIG_IP_NF_MANGLE=y +# CONFIG_IP_NF_TARGET_CLUSTERIP is not set +CONFIG_IP_NF_TARGET_ECN=y +CONFIG_IP_NF_TARGET_TTL=y +CONFIG_IP_NF_RAW=y +CONFIG_IP_NF_ARPTABLES=y +CONFIG_IP_NF_ARPFILTER=y +CONFIG_IP_NF_ARP_MANGLE=y + +# +# IPv6: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV6=y +CONFIG_NF_CONNTRACK_IPV6=y +# CONFIG_NF_DUP_IPV6 is not set +CONFIG_NF_REJECT_IPV6=y +# CONFIG_NF_LOG_IPV6 is not set +# CONFIG_NF_NAT_IPV6 is not set +CONFIG_IP6_NF_IPTABLES=y +# CONFIG_IP6_NF_MATCH_AH is not set +# CONFIG_IP6_NF_MATCH_EUI64 is not set +# CONFIG_IP6_NF_MATCH_FRAG is not set +# CONFIG_IP6_NF_MATCH_OPTS is not set +# CONFIG_IP6_NF_MATCH_HL is not set +# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set +# CONFIG_IP6_NF_MATCH_MH is not set +CONFIG_IP6_NF_MATCH_RPFILTER=y +CONFIG_IP6_NF_MATCH_RT=y +# CONFIG_IP6_NF_TARGET_HL is not set +CONFIG_IP6_NF_FILTER=y +CONFIG_IP6_NF_TARGET_REJECT=y +# CONFIG_IP6_NF_TARGET_SYNPROXY is not set +CONFIG_IP6_NF_MANGLE=y +CONFIG_IP6_NF_RAW=y +# CONFIG_IP6_NF_NAT is not set +# CONFIG_BRIDGE_NF_EBTABLES is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_L2TP is not set +CONFIG_STP=y +CONFIG_GARP=y +CONFIG_BRIDGE=y +CONFIG_BRIDGE_IGMP_SNOOPING=y +# CONFIG_BRIDGE_VLAN_FILTERING is not set +CONFIG_HAVE_NET_DSA=y +CONFIG_VLAN_8021Q=y +CONFIG_VLAN_8021Q_GVRP=y +# CONFIG_VLAN_8021Q_MVRP is not set +# CONFIG_DECNET is not set +CONFIG_LLC=y +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_PHONET is not set +# CONFIG_6LOWPAN is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set +CONFIG_DNS_RESOLVER=y +# CONFIG_BATMAN_ADV is not set +# CONFIG_OPENVSWITCH is not set +# CONFIG_VSOCKETS is not set +# CONFIG_NETLINK_MMAP is not set +# CONFIG_NETLINK_DIAG is not set +# CONFIG_MPLS is not set +# CONFIG_HSR is not set +# CONFIG_NET_SWITCHDEV is not set +# CONFIG_NET_L3_MASTER_DEV is not set +CONFIG_RPS=y +CONFIG_RFS_ACCEL=y +CONFIG_XPS=y +CONFIG_NET_RX_BUSY_POLL=y +CONFIG_BQL=y +# CONFIG_BPF_JIT is not set +CONFIG_NET_FLOW_LIMIT=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +CONFIG_FIB_RULES=y +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set +# CONFIG_NFC is not set +# CONFIG_LWTUNNEL is not set +CONFIG_HAVE_BPF_JIT=y + +# +# Device Drivers +# +CONFIG_ARM_AMBA=y +# CONFIG_TEGRA_AHB is not set + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER=y +CONFIG_UEVENT_HELPER_PATH="/sbin/mdev" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set +CONFIG_ALLOW_DEV_COREDUMP=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_GENERIC_CPU_DEVICES is not set +# CONFIG_DMA_SHARED_BUFFER is not set +CONFIG_DMA_CMA=y + +# +# Default contiguous memory area size: +# +CONFIG_CMA_SIZE_MBYTES=32 +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 + +# +# Bus devices +# +# CONFIG_BRCMSTB_GISB_ARB is not set +# CONFIG_VEXPRESS_CONFIG is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +CONFIG_MTD_TESTS=m +# 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 + +# +# 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=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_STAA=y +CONFIG_MTD_CFI_UTIL=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_PHYSMAP is not set +# CONFIG_MTD_PHYSMAP_OF is not set +# CONFIG_MTD_NOR_XGS_IPROC is not set +# CONFIG_MTD_IMPA7 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_IPROC=y +# 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_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_SM_COMMON is not set +# CONFIG_MTD_NAND_DENALI_PCI is not set +# CONFIG_MTD_NAND_DENALI_DT is not set +# CONFIG_MTD_NAND_GPIO is not set +# CONFIG_MTD_NAND_OMAP_BCH_BUILD is not set +CONFIG_MTD_NAND_IDS=y +# 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_XGS_IPROC=y +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_NAND_HISI504 is not set +# CONFIG_MTD_ONENAND 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 is not set +# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set +CONFIG_MTD_SPI_NOR_IPROC=y +CONFIG_M25PXX_STAY_IN_3BYTE_MODE=y +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_ADDRESS=y +CONFIG_OF_ADDRESS_PCI=y +CONFIG_OF_IRQ=y +CONFIG_OF_NET=y +CONFIG_OF_MDIO=y +CONFIG_OF_PCI=y +CONFIG_OF_PCI_IRQ=y +CONFIG_OF_MTD=y +CONFIG_OF_RESERVED_MEM=y +# CONFIG_OF_OVERLAY is not set +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_NULL_BLK is not set +# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_DRBD is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MG_DISK is not set +# CONFIG_BLK_DEV_RBD is not set +# CONFIG_BLK_DEV_RSXX is not set +# CONFIG_BLK_DEV_NVME is not set + +# +# Misc devices +# +# CONFIG_AD525X_DPOT 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 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_HP_ILO is not set +# CONFIG_APDS9802ALS is not set +# CONFIG_ISL29003 is not set +# CONFIG_ISL29020 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_SENSORS_BH1780 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_TI_DAC7512 is not set +# CONFIG_BMP085_I2C is not set +# CONFIG_BMP085_SPI is not set +# CONFIG_USB_SWITCH_FSA9480 is not set +# CONFIG_LATTICE_ECP3_CONFIG is not set +# CONFIG_SRAM is not set +# 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 is not set +# CONFIG_EEPROM_93XX46 is not set +# CONFIG_CB710_CORE is not set + +# +# Texas Instruments shared transport line discipline +# +# CONFIG_TI_ST is not set + +# +# Altera FPGA firmware download module +# +# CONFIG_ALTERA_STAPL is not set + +# +# Intel MIC Bus Driver +# + +# +# SCIF Bus Driver +# + +# +# Intel MIC Host Driver +# + +# +# Intel MIC Card Driver +# + +# +# SCIF Driver +# + +# +# Intel MIC Coprocessor State Management (COSM) Drivers +# +# CONFIG_ECHO is not set +# CONFIG_CXL_BASE is not set +# CONFIG_CXL_KERNEL_API is not set +# CONFIG_CXL_EEH is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE 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_NETLINK is not set +# CONFIG_SCSI_MQ_DEFAULT is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=y +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +CONFIG_CHR_DEV_SG=y +# CONFIG_CHR_DEV_SCH is not set +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +# CONFIG_SCSI_SCAN_ASYNC is not set + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_ISCSI_BOOT_SYSFS is not set +# 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 is not set +# CONFIG_SCSI_MVUMI 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_UFSHCD is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_SNIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_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_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_TARGET_CORE is not set +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_FIREWIRE is not set +# CONFIG_FIREWIRE_NOSY is not set +CONFIG_NETDEVICES=y +CONFIG_NET_CORE=y +CONFIG_BONDING=y +# CONFIG_DUMMY is not set +# CONFIG_EQUALIZER is not set +# CONFIG_NET_FC is not set +# CONFIG_NET_TEAM is not set +# CONFIG_MACVLAN is not set +# CONFIG_IPVLAN is not set +# CONFIG_VXLAN is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_TUN is not set +# CONFIG_TUN_VNET_CROSS_LE is not set +# CONFIG_VETH is not set +# CONFIG_NLMON is not set +# CONFIG_ARCNET is not set + +# +# CAIF transport drivers +# + +# +# Distributed Switch Architecture drivers +# +# CONFIG_NET_DSA_MV88E6XXX is not set +# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set +CONFIG_ETHERNET=y +CONFIG_NET_VENDOR_3COM=y +# CONFIG_VORTEX is not set +# CONFIG_TYPHOON is not set +CONFIG_NET_VENDOR_ADAPTEC=y +# CONFIG_ADAPTEC_STARFIRE is not set +CONFIG_NET_VENDOR_AGERE=y +# CONFIG_ET131X is not set +CONFIG_NET_VENDOR_ALTEON=y +# CONFIG_ACENIC is not set +# CONFIG_ALTERA_TSE is not set +CONFIG_NET_VENDOR_AMD=y +# CONFIG_AMD8111_ETH is not set +# CONFIG_PCNET32 is not set +CONFIG_NET_VENDOR_ARC=y +# CONFIG_ARC_EMAC is not set +CONFIG_NET_VENDOR_ATHEROS=y +# CONFIG_ATL2 is not set +# CONFIG_ATL1 is not set +# CONFIG_ATL1E is not set +# CONFIG_ATL1C is not set +# CONFIG_ALX is not set +# CONFIG_NET_VENDOR_AURORA is not set +CONFIG_NET_CADENCE=y +# CONFIG_MACB is not set +CONFIG_NET_VENDOR_BROADCOM=y +# CONFIG_B44 is not set +# CONFIG_BCMGENET is not set +# CONFIG_BNX2 is not set +# CONFIG_CNIC is not set +CONFIG_TIGON3=y +# CONFIG_BNX2X is not set +# CONFIG_SYSTEMPORT is not set +# CONFIG_BNXT is not set +CONFIG_GMAC_XGS_IPROC=y + +# +# Broadcom HND network devices +# +CONFIG_HND=y +CONFIG_ET=y +# CONFIG_ET_NAPI2_POLL is not set +# CONFIG_BCM_IPROC_GMAC_ACP is not set +# CONFIG_BCM_IPROC_GMAC_PREFETCH is not set +# CONFIG_BCM_IPROC_GMAC_LOCK_OPT is not set +# CONFIG_BCM_IPROC_GMAC_RWREG_OPT is not set +# CONFIG_BCM_IPROC_GMAC_SG is not set +CONFIG_IPROC_SDK_MGT_PORT_HANDOFF=y +# CONFIG_IPROC_2STAGE_RX is not set +# CONFIG_SERDES_ASYMMETRIC_MODE is not set +# CONFIG_JUMBO_FRAME is not set +CONFIG_MDIO_XGS_IPROC=y +CONFIG_NET_VENDOR_BROCADE=y +# CONFIG_BNA is not set +CONFIG_NET_VENDOR_CAVIUM=y +CONFIG_NET_VENDOR_CHELSIO=y +# CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set +# CONFIG_CHELSIO_T4 is not set +# CONFIG_CHELSIO_T4VF is not set +CONFIG_NET_VENDOR_CIRRUS=y +# CONFIG_CS89x0 is not set +CONFIG_NET_VENDOR_CISCO=y +# CONFIG_ENIC is not set +# CONFIG_DM9000 is not set +# CONFIG_DNET is not set +CONFIG_NET_VENDOR_DEC=y +# CONFIG_NET_TULIP is not set +CONFIG_NET_VENDOR_DLINK=y +# CONFIG_DL2K is not set +# CONFIG_SUNDANCE is not set +CONFIG_NET_VENDOR_EMULEX=y +# CONFIG_BE2NET is not set +CONFIG_NET_VENDOR_EZCHIP=y +# CONFIG_EZCHIP_NPS_MANAGEMENT_ENET is not set +CONFIG_NET_VENDOR_EXAR=y +# CONFIG_S2IO is not set +# CONFIG_VXGE is not set +CONFIG_NET_VENDOR_FARADAY=y +# CONFIG_FTMAC100 is not set +# CONFIG_FTGMAC100 is not set +CONFIG_NET_VENDOR_HISILICON=y +# CONFIG_HIX5HD2_GMAC is not set +# CONFIG_HIP04_ETH is not set +# CONFIG_HNS is not set +# CONFIG_HNS_DSAF is not set +# CONFIG_HNS_ENET is not set +CONFIG_NET_VENDOR_HP=y +# CONFIG_HP100 is not set +CONFIG_NET_VENDOR_INTEL=y +# CONFIG_E100 is not set +# CONFIG_E1000 is not set +# CONFIG_E1000E is not set +# CONFIG_IGB is not set +# CONFIG_IGBVF is not set +# CONFIG_IXGB is not set +# CONFIG_IXGBE is not set +# CONFIG_IXGBEVF is not set +# CONFIG_I40E is not set +# CONFIG_I40EVF is not set +# CONFIG_FM10K is not set +CONFIG_NET_VENDOR_I825XX=y +# CONFIG_JME is not set +CONFIG_NET_VENDOR_MARVELL=y +# CONFIG_MVMDIO is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +CONFIG_NET_VENDOR_MELLANOX=y +# CONFIG_MLX4_EN is not set +# CONFIG_MLX4_CORE is not set +# CONFIG_MLX5_CORE is not set +# CONFIG_MLXSW_CORE is not set +CONFIG_NET_VENDOR_MICREL=y +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_KSZ884X_PCI is not set +CONFIG_NET_VENDOR_MICROCHIP=y +# CONFIG_ENC28J60 is not set +# CONFIG_ENCX24J600 is not set +CONFIG_NET_VENDOR_MYRI=y +# CONFIG_MYRI10GE is not set +# CONFIG_FEALNX is not set +CONFIG_NET_VENDOR_NATSEMI=y +# CONFIG_NATSEMI is not set +# CONFIG_NS83820 is not set +CONFIG_NET_VENDOR_8390=y +# CONFIG_AX88796 is not set +# CONFIG_NE2K_PCI is not set +CONFIG_NET_VENDOR_NVIDIA=y +# CONFIG_FORCEDETH is not set +CONFIG_NET_VENDOR_OKI=y +# CONFIG_ETHOC is not set +CONFIG_NET_PACKET_ENGINE=y +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +CONFIG_NET_VENDOR_QLOGIC=y +# CONFIG_QLA3XXX is not set +# CONFIG_QLCNIC is not set +# CONFIG_QLGE is not set +# CONFIG_NETXEN_NIC is not set +# CONFIG_QED is not set +CONFIG_NET_VENDOR_QUALCOMM=y +# CONFIG_QCA7000 is not set +CONFIG_NET_VENDOR_REALTEK=y +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_R8169 is not set +CONFIG_NET_VENDOR_RENESAS=y +CONFIG_NET_VENDOR_RDC=y +# CONFIG_R6040 is not set +CONFIG_NET_VENDOR_ROCKER=y +CONFIG_NET_VENDOR_SAMSUNG=y +# CONFIG_SXGBE_ETH is not set +CONFIG_NET_VENDOR_SEEQ=y +CONFIG_NET_VENDOR_SILAN=y +# CONFIG_SC92031 is not set +CONFIG_NET_VENDOR_SIS=y +# CONFIG_SIS900 is not set +# CONFIG_SIS190 is not set +# CONFIG_SFC is not set +CONFIG_NET_VENDOR_SMSC=y +# CONFIG_SMC91X is not set +# CONFIG_EPIC100 is not set +# CONFIG_SMC911X is not set +# CONFIG_SMSC911X is not set +# CONFIG_SMSC9420 is not set +CONFIG_NET_VENDOR_STMICRO=y +# CONFIG_STMMAC_ETH is not set +CONFIG_NET_VENDOR_SUN=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NIU is not set +CONFIG_NET_VENDOR_SYNOPSYS=y +# CONFIG_SYNOPSYS_DWC_ETH_QOS is not set +CONFIG_NET_VENDOR_TEHUTI=y +# CONFIG_TEHUTI is not set +CONFIG_NET_VENDOR_TI=y +# CONFIG_TI_CPSW_ALE is not set +# CONFIG_TLAN is not set +CONFIG_NET_VENDOR_VIA=y +# CONFIG_VIA_RHINE is not set +# CONFIG_VIA_VELOCITY is not set +CONFIG_NET_VENDOR_WIZNET=y +# CONFIG_WIZNET_W5100 is not set +# CONFIG_WIZNET_W5300 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_AQUANTIA_PHY is not set +# CONFIG_AT803X_PHY is not set +# CONFIG_AMD_PHY is not set +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_TERANETICS_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_BCM7XXX_PHY is not set +# CONFIG_BCM87XX_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_DP83848_PHY is not set +# CONFIG_DP83867_PHY is not set +# CONFIG_MICROCHIP_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +# CONFIG_MDIO_BUS_MUX_GPIO is not set +# CONFIG_MDIO_BUS_MUX_MMIOREG is not set +# CONFIG_MDIO_BCM_UNIMAC is not set +# CONFIG_MICREL_KS8995MA is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +CONFIG_USB_NET_DRIVERS=y +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_RTL8152 is not set +# CONFIG_USB_LAN78XX is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_IPHETH is not set +# CONFIG_WLAN is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_VMXNET3 is not set +# CONFIG_ISDN is not set +# CONFIG_NVM is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_AMBAKMI is not set +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# 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_USERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_TTY=y +# CONFIG_VT is not set +CONFIG_UNIX98_PTYS=y +CONFIG_DEVPTS_MULTIPLE_INSTANCES=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_DEVMEM=y +CONFIG_DEVKMEM=y + +# +# Serial drivers +# +CONFIG_SERIAL_EARLYCON=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_DMA=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_NR_UARTS=2 +CONFIG_SERIAL_8250_RUNTIME_UARTS=2 +CONFIG_SERIAL_8250_EXTENDED=y +# CONFIG_SERIAL_8250_MANY_PORTS is not set +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_DETECT_IRQ=y +CONFIG_SERIAL_8250_RSA=y +CONFIG_SERIAL_8250_FSL=y +CONFIG_SERIAL_8250_DW=y +# CONFIG_SERIAL_8250_EM is not set +# CONFIG_SERIAL_8250_RT288X is not set +# CONFIG_SERIAL_8250_INGENIC is not set +# CONFIG_SERIAL_8250_MID is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +# CONFIG_SERIAL_AMBA_PL011 is not set +# 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_OF_PLATFORM=y +# CONFIG_SERIAL_SCCNXP is not set +# CONFIG_SERIAL_SC16IS7XX is not set +# CONFIG_SERIAL_BCM63XX is not set +# 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 is not set +# CONFIG_SERIAL_ARC is not set +# CONFIG_SERIAL_RP2 is not set +# CONFIG_SERIAL_FSL_LPUART is not set +# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set +# CONFIG_SERIAL_ST_ASC is not set +# CONFIG_SERIAL_STM32 is not set +# CONFIG_TTY_PRINTK is not set +# CONFIG_HVC_DCC is not set +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +# CONFIG_HW_RANDOM_XGS_IPROC_RNG is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_DEVPORT=y +# CONFIG_XILLYBUS is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +# CONFIG_I2C_COMPAT is not set +CONFIG_I2C_CHARDEV=y +# CONFIG_I2C_MUX is not set +# CONFIG_I2C_HELPER_AUTO is not set +# CONFIG_I2C_SMBUS is not set + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# + +# +# PC SMBus host controller drivers +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_ISCH is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +CONFIG_I2C_XGS_IPROC=y +# CONFIG_SMBUS_XGS_IPROC is not set +# 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 is not set +# CONFIG_I2C_NOMADIK is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_PXA_PCI 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_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 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_ALTERA is not set +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_CADENCE is not set +# CONFIG_SPI_GPIO is not set +# CONFIG_SPI_FSL_SPI is not set +# CONFIG_SPI_OC_TINY is not set +# CONFIG_SPI_PL022 is not set +# CONFIG_SPI_PXA2XX is not set +# CONFIG_SPI_PXA2XX_PCI 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 +CONFIG_SPI_XGS_IPROC=y +CONFIG_IPROC_QSPI_SINGLE_MODE=y +# CONFIG_IPROC_QSPI_DUAL_MODE is not set +# CONFIG_IPROC_QSPI_QUAD_MODE is not set +CONFIG_IPROC_QSPI_MAX_HZ=62500000 +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set +# CONFIG_SPMI is not set +# CONFIG_HSI is not set + +# +# PPS support +# +CONFIG_PPS=y +# CONFIG_PPS_DEBUG is not set + +# +# PPS clients support +# +# CONFIG_PPS_CLIENT_KTIMER is not set +# CONFIG_PPS_CLIENT_LDISC is not set +# CONFIG_PPS_CLIENT_GPIO is not set + +# +# PPS generators support +# + +# +# PTP clock support +# +CONFIG_PTP_1588_CLOCK=y + +# +# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. +# +CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_DEVRES=y +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_XGS_IPROC=y +# CONFIG_GPIO_DWAPB is not set +# CONFIG_GPIO_EM is not set +# CONFIG_GPIO_GENERIC_PLATFORM is not set +# CONFIG_GPIO_GRGPIO is not set +# CONFIG_GPIO_PL061 is not set +# CONFIG_GPIO_VX855 is not set +# CONFIG_GPIO_XILINX is not set +# CONFIG_GPIO_ZEVIO is not set +# CONFIG_GPIO_ZX 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_SX150X is not set + +# +# MFD GPIO expanders +# + +# +# PCI GPIO expanders +# +# CONFIG_GPIO_AMD8111 is not set +# CONFIG_GPIO_BT8XX is not set +# CONFIG_GPIO_ML_IOH is not set +# CONFIG_GPIO_RDC321X is not set + +# +# SPI GPIO expanders +# +# CONFIG_GPIO_74X164 is not set +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# SPI or I2C GPIO expanders +# +# CONFIG_GPIO_MCP23S08 is not set + +# +# USB GPIO expanders +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_POWER_AVS is not set +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Native drivers +# +# CONFIG_SENSORS_AD7314 is not set +# CONFIG_SENSORS_AD7414 is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7310 is not set +# CONFIG_SENSORS_ADT7410 is not set +# CONFIG_SENSORS_ADT7411 is not set +# CONFIG_SENSORS_ADT7462 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7475 is not set +# CONFIG_SENSORS_ASC7621 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS620 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_I5K_AMB is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_G760A is not set +# CONFIG_SENSORS_G762 is not set +# CONFIG_SENSORS_GPIO_FAN is not set +# CONFIG_SENSORS_HIH6130 is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_JC42 is not set +# CONFIG_SENSORS_POWR1220 is not set +# CONFIG_SENSORS_LINEAGE is not set +# CONFIG_SENSORS_LTC2945 is not set +# CONFIG_SENSORS_LTC4151 is not set +# CONFIG_SENSORS_LTC4215 is not set +# CONFIG_SENSORS_LTC4222 is not set +# CONFIG_SENSORS_LTC4245 is not set +# CONFIG_SENSORS_LTC4260 is not set +# CONFIG_SENSORS_LTC4261 is not set +# CONFIG_SENSORS_MAX1111 is not set +# CONFIG_SENSORS_MAX16065 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX1668 is not set +# CONFIG_SENSORS_MAX197 is not set +# CONFIG_SENSORS_MAX6639 is not set +# CONFIG_SENSORS_MAX6642 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_MAX6697 is not set +# CONFIG_SENSORS_MAX31790 is not set +# CONFIG_SENSORS_HTU21 is not set +# CONFIG_SENSORS_MCP3021 is not set +# CONFIG_SENSORS_ADCXX is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_LM73 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_LM95234 is not set +# CONFIG_SENSORS_LM95241 is not set +# CONFIG_SENSORS_LM95245 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_NTC_THERMISTOR is not set +# CONFIG_SENSORS_NCT6683 is not set +# CONFIG_SENSORS_NCT6775 is not set +# CONFIG_SENSORS_NCT7802 is not set +# CONFIG_SENSORS_NCT7904 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_PMBUS is not set +# CONFIG_SENSORS_SHT15 is not set +# CONFIG_SENSORS_SHT21 is not set +# CONFIG_SENSORS_SHTC1 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_EMC1403 is not set +# CONFIG_SENSORS_EMC2103 is not set +# CONFIG_SENSORS_EMC6W201 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SCH56XX_COMMON is not set +# CONFIG_SENSORS_SCH5627 is not set +# CONFIG_SENSORS_SCH5636 is not set +# CONFIG_SENSORS_SMM665 is not set +# CONFIG_SENSORS_ADC128D818 is not set +# CONFIG_SENSORS_ADS1015 is not set +# CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_ADS7871 is not set +# CONFIG_SENSORS_AMC6821 is not set +# CONFIG_SENSORS_INA209 is not set +# CONFIG_SENSORS_INA2XX is not set +# CONFIG_SENSORS_TC74 is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_TMP102 is not set +# CONFIG_SENSORS_TMP103 is not set +# CONFIG_SENSORS_TMP401 is not set +# CONFIG_SENSORS_TMP421 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83795 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83L786NG is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_THERMAL is not set +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_CORE=y +# CONFIG_WATCHDOG_NOWAYOUT 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_ARM_SP805_WATCHDOG is not set +# CONFIG_CADENCE_WATCHDOG is not set +# CONFIG_DW_WATCHDOG is not set +# CONFIG_MAX63XX_WATCHDOG is not set +CONFIG_XGS_IPROC_SP805_WDT=y +# CONFIG_ALIM7101_WDT is not set +# CONFIG_I6300ESB_WDT is not set +# CONFIG_BCM7038_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 +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set +CONFIG_BCMA_POSSIBLE=y + +# +# Broadcom specific AMBA +# +# CONFIG_BCMA is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE 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_AXP20X is not set +# CONFIG_MFD_CROS_EC 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_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_LPC_ICH is not set +# CONFIG_LPC_SCH is not set +# CONFIG_INTEL_SOC_PMIC is not set +# 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_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 is not set +# CONFIG_MFD_MENF21BMC is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_MFD_VIPERBOARD is not set +# CONFIG_MFD_RETU is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_PM8921_CORE is not set +# CONFIG_MFD_RDC321X is not set +# CONFIG_MFD_RTSX_PCI is not set +# CONFIG_MFD_RT5033 is not set +# CONFIG_MFD_RTSX_USB 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 is not set +# CONFIG_MFD_TI_AM335X_TSCADC is not set +# CONFIG_MFD_LP3943 is not set +# CONFIG_MFD_LP8788 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_TPS65090 is not set +# CONFIG_MFD_TPS65217 is not set +# CONFIG_MFD_TPS65218 is not set +# CONFIG_MFD_TPS6586X is not set +# CONFIG_MFD_TPS65910 is not set +# CONFIG_MFD_TPS65912 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 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_TMIO 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_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_VGA_ARB is not set +# CONFIG_DRM is not set + +# +# Frame buffer Devices +# +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_VGASTATE is not set +# CONFIG_SOUND 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_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +CONFIG_USB_DEFAULT_PERSIST=y +CONFIG_USB_DYNAMIC_MINORS=y +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_ULPI_BUS 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 is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EHCI_PCI=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_USB_EHCI_XGS_IPROC=y +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +# CONFIG_USB_FOTG210_HCD is not set +# CONFIG_USB_MAX3421_HCD is not set +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PCI=y +CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_OHCI_XGS_IPROC=y +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HCD_TEST_MODE is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_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_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_STORAGE_ENE_UB6250 is not set +# CONFIG_USB_UAS is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USBIP_CORE 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_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_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_HSIC_USB3503 is not set +# CONFIG_USB_LINK_LAYER_TEST is not set +# CONFIG_USB_CHAOSKEY is not set + +# +# USB Physical Layer drivers +# +CONFIG_USB_PHY=y +# CONFIG_NOP_USB_XCEIV is not set +# CONFIG_AM335X_PHY_USB is not set +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_USB_ISP1301 is not set +# CONFIG_USB_ULPI is not set +CONFIG_USBPHY_XGS_IPROC=y +CONFIG_USB_GADGET=y +# 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 + +# +# 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_M66592 is not set +# CONFIG_USB_BDC_UDC is not set +# 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_XGS_IPROC_UDC=m +# CONFIG_USB_DUMMY_HCD is not set +CONFIG_USB_LIBCOMPOSITE=m +CONFIG_USB_F_ACM=m +CONFIG_USB_U_SERIAL=m +CONFIG_USB_F_SERIAL=m +CONFIG_USB_F_OBEX=m +# CONFIG_USB_CONFIGFS is not set +# CONFIG_USB_ZERO is not set +# CONFIG_USB_ETH 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_G_SERIAL=m +# 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_UWB is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_MINORS=8 +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_ARMMMCI is not set +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_IO_ACCESSORS=y +# CONFIG_MMC_SDHCI_PCI is not set +# CONFIG_MMC_SDHCI_PLTFM 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_TOSHIBA_PCI is not set +# CONFIG_MMC_MTK is not set +CONFIG_MMC_SDHCI_XGS_IPROC=y +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND is not set +CONFIG_EDAC_ATOMIC_SCRUB=y +CONFIG_EDAC_SUPPORT=y +# CONFIG_EDAC is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set +CONFIG_DMADEVICES=y +CONFIG_DMADEVICES_DEBUG=y +CONFIG_DMADEVICES_VDEBUG=y + +# +# DMA Devices +# +CONFIG_DMA_ENGINE=y +CONFIG_DMA_OF=y +# CONFIG_AMBA_PL08X is not set +# CONFIG_FSL_EDMA is not set +# CONFIG_INTEL_IDMA64 is not set +# CONFIG_NBPFAXI_DMA is not set +CONFIG_PL330_DMA=y +# CONFIG_XGS_IPROC_DMA330_DMA 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 is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set +# CONFIG_VIRT_DRIVERS is not set + +# +# Virtio drivers +# +# CONFIG_VIRTIO_PCI is not set +# CONFIG_VIRTIO_MMIO is not set + +# +# Microsoft Hyper-V guest support +# +# CONFIG_STAGING is not set +# CONFIG_CHROME_PLATFORMS is not set +CONFIG_CLKDEV_LOOKUP=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_COMMON_CLK=y + +# +# Common Clock Framework +# +# CONFIG_COMMON_CLK_SI5351 is not set +# CONFIG_COMMON_CLK_SI514 is not set +# CONFIG_COMMON_CLK_SI570 is not set +# CONFIG_COMMON_CLK_CDCE925 is not set +# CONFIG_CLK_QORIQ is not set +# CONFIG_COMMON_CLK_PXA is not set +# CONFIG_COMMON_CLK_CDCE706 is not set +CONFIG_COMMON_CLK_IPROC=y +CONFIG_CLK_XGS_IPROC=y + +# +# Hardware Spinlock drivers +# + +# +# Clock Source drivers +# +CONFIG_CLKSRC_OF=y +CONFIG_CLKSRC_PROBE=y +CONFIG_ARM_GLOBAL_TIMER=y +# CONFIG_ARM_TIMER_SP804 is not set +CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK=y +# CONFIG_ATMEL_PIT is not set +# CONFIG_SH_TIMER_CMT is not set +# CONFIG_SH_TIMER_MTU2 is not set +# CONFIG_SH_TIMER_TMU is not set +# CONFIG_EM_TIMER_STI is not set +# CONFIG_MAILBOX is not set +CONFIG_IOMMU_SUPPORT=y + +# +# Generic IOMMU Pagetable Support +# +# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set +# CONFIG_ARM_SMMU is not set + +# +# Remoteproc drivers +# +# CONFIG_STE_MODEM_RPROC is not set + +# +# Rpmsg drivers +# + +# +# SOC (System On Chip) specific Drivers +# +# CONFIG_SOC_BRCMSTB is not set +CONFIG_SOC_XGS_IPROC=y +# CONFIG_SUNXI_SRAM is not set +# CONFIG_SOC_TI is not set +# CONFIG_PM_DEVFREQ is not set +# CONFIG_EXTCON is not set +# CONFIG_MEMORY is not set +# CONFIG_IIO is not set +# CONFIG_NTB is not set +# CONFIG_VME_BUS is not set +# CONFIG_PWM is not set +CONFIG_IRQCHIP=y +CONFIG_ARM_GIC=y +# CONFIG_IPACK_BUS is not set +# CONFIG_RESET_CONTROLLER is not set +# CONFIG_FMC is not set + +# +# PHY Subsystem +# +# CONFIG_GENERIC_PHY is not set +# CONFIG_PHY_PXA_28NM_HSIC is not set +# CONFIG_PHY_PXA_28NM_USB2 is not set +# CONFIG_BCM_KONA_USB2_PHY is not set +# CONFIG_POWERCAP is not set +# CONFIG_MCB is not set + +# +# Performance monitor support +# +# CONFIG_RAS is not set +# CONFIG_THUNDERBOLT is not set + +# +# Android +# +# CONFIG_ANDROID is not set +# CONFIG_NVMEM is not set +# CONFIG_STM is not set +# CONFIG_STM_DUMMY is not set +# CONFIG_STM_SOURCE_CONSOLE is not set +# CONFIG_INTEL_TH is not set + +# +# FPGA Configuration Support +# +# CONFIG_FPGA is not set + +# +# Firmware Drivers +# +# CONFIG_FIRMWARE_MEMMAP is not set + +# +# File systems +# +CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_EXT4_FS=y +# CONFIG_EXT4_FS_POSIX_ACL is not set +# CONFIG_EXT4_FS_SECURITY is not set +# 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 is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +# CONFIG_F2FS_FS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_EXPORTFS=y +CONFIG_FILE_LOCKING=y +# CONFIG_FSNOTIFY is not set +# CONFIG_DNOTIFY is not set +# CONFIG_INOTIFY_USER is not set +# CONFIG_FANOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_QUOTACTL is not set +CONFIG_AUTOFS4_FS=y +# CONFIG_FUSE_FS is not set +CONFIG_OVERLAY_FS=y + +# +# 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_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 is not set +# CONFIG_PROC_CHILDREN is not set +CONFIG_KERNFS=y +CONFIG_SYSFS=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_CONFIGFS_FS=m +CONFIG_MISC_FILESYSTEMS=y +# 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=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_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_LOGFS is not set +# CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS 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 is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V2=y +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_SWAP=y +# CONFIG_NFS_V4_1 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFS_USE_LEGACY_DNS is not set +CONFIG_NFS_USE_KERNEL_DNS=y +CONFIG_NFSD=y +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_V4 is not set +CONFIG_GRACE_PERIOD=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_SUNRPC_SWAP=y +# CONFIG_SUNRPC_DEBUG is not set +# CONFIG_CEPH_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +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 is not set +# CONFIG_DLM is not set + +# +# Kernel hacking +# + +# +# printk and dmesg options +# +# CONFIG_PRINTK_TIME is not set +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=y +# CONFIG_DEBUG_INFO_REDUCED is not set +# CONFIG_DEBUG_INFO_SPLIT is not set +# CONFIG_DEBUG_INFO_DWARF4 is not set +# CONFIG_GDB_SCRIPTS is not set +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +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_FRAME_POINTER=y +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 +CONFIG_DEBUG_KERNEL=y + +# +# Memory Debugging +# +# CONFIG_PAGE_EXTENSION is not set +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_DEBUG_OBJECTS 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_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_PER_CPU_MAPS is not set +# CONFIG_DEBUG_SHIRQ is not set + +# +# Debug Lockups and Hangs +# +# CONFIG_LOCKUP_DETECTOR is not set +# CONFIG_DETECT_HUNG_TASK is not set +# CONFIG_PANIC_ON_OOPS is not set +CONFIG_PANIC_ON_OOPS_VALUE=0 +CONFIG_PANIC_TIMEOUT=0 +# CONFIG_SCHED_DEBUG is not set +# CONFIG_SCHED_INFO is not set +# CONFIG_SCHEDSTATS is not set +# CONFIG_SCHED_STACK_END_CHECK is not set +# CONFIG_DEBUG_TIMEKEEPING is not set +# CONFIG_TIMER_STATS is not set +CONFIG_DEBUG_PREEMPT=y + +# +# Lock Debugging (spinlocks, mutexes, etc...) +# +# 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_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT 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_STACKTRACE 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_PROVE_RCU is not set +# CONFIG_SPARSE_RCU_POINTER is not set +# CONFIG_TORTURE_TEST is not set +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_RCU_CPU_STALL_TIMEOUT=60 +# CONFIG_RCU_TRACE is not set +# CONFIG_RCU_EQS_DEBUG is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_NOTIFIER_ERROR_INJECTION is not set +# CONFIG_FAULT_INJECTION is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set + +# +# Runtime Testing +# +# CONFIG_LKDTM is not set +# CONFIG_TEST_LIST_SORT 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_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_RHASHTABLE is not set +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_TEST_LKM is not set +# CONFIG_TEST_USER_COPY is not set +# CONFIG_TEST_BPF is not set +# CONFIG_TEST_FIRMWARE is not set +# CONFIG_TEST_UDELAY is not set +# CONFIG_MEMTEST is not set +# CONFIG_TEST_STATIC_KEYS is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_ARM_PTDUMP is not set +# CONFIG_STRICT_DEVMEM is not set +# CONFIG_ARM_UNWIND is not set +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_LL is not set +CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" +# CONFIG_DEBUG_UART_8250 is not set +CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" +# CONFIG_PID_IN_CONTEXTIDR is not set +# CONFIG_DEBUG_SET_MODULE_RONX is not set +# CONFIG_CORESIGHT is not set + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_PERSISTENT_KEYRINGS is not set +# CONFIG_ENCRYPTED_KEYS is not set +# CONFIG_SECURITY_DMESG_RESTRICT is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=m +CONFIG_CRYPTO_PCOMP2=y +CONFIG_CRYPTO_AKCIPHER2=y +# CONFIG_CRYPTO_RSA is not set +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_USER is not set +CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y +# CONFIG_CRYPTO_GF128MUL is not set +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_NULL2=y +# CONFIG_CRYPTO_PCRYPT is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_MCRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_CHACHA20POLY1305 is not set +# CONFIG_CRYPTO_SEQIV is not set +CONFIG_CRYPTO_ECHAINIV=m + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_ECB is not set +# 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 is not set +CONFIG_CRYPTO_HMAC=m +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=y +# CONFIG_CRYPTO_CRC32 is not set +# CONFIG_CRYPTO_CRCT10DIF is not set +# CONFIG_CRYPTO_GHASH is not set +# CONFIG_CRYPTO_POLY1305 is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# 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 is not set +CONFIG_CRYPTO_SHA256=m +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 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=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_CHACHA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_ZLIB is not set +CONFIG_CRYPTO_LZO=y +# CONFIG_CRYPTO_842 is not set +# CONFIG_CRYPTO_LZ4 is not set +# CONFIG_CRYPTO_LZ4HC is not set + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m +CONFIG_CRYPTO_DRBG_MENU=m +CONFIG_CRYPTO_DRBG_HMAC=y +# CONFIG_CRYPTO_DRBG_HASH is not set +# CONFIG_CRYPTO_DRBG_CTR is not set +CONFIG_CRYPTO_DRBG=m +CONFIG_CRYPTO_JITTERENTROPY=m +# CONFIG_CRYPTO_USER_API_HASH is not set +# CONFIG_CRYPTO_USER_API_SKCIPHER is not set +# CONFIG_CRYPTO_USER_API_RNG is not set +# CONFIG_CRYPTO_USER_API_AEAD is not set +CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_ASYMMETRIC_KEY_TYPE is not set + +# +# Certificates for signature checking +# +# CONFIG_SYSTEM_TRUSTED_KEYRING is not set +# CONFIG_ARM_CRYPTO is not set +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +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_GENERIC_IO=y +CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y +# CONFIG_CRC_CCITT is not set +CONFIG_CRC16=y +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +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_CRC7 is not set +# CONFIG_LIBCRC32C is not set +# CONFIG_CRC8 is not set +# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set +# CONFIG_RANDOM32_SELFTEST is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_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_GENERIC_ALLOCATOR=y +CONFIG_ASSOCIATIVE_ARRAY=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HAS_DMA=y +CONFIG_CPU_RMAP=y +CONFIG_DQL=y +CONFIG_NLATTR=y +CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y +# CONFIG_CORDIC is not set +# CONFIG_DDR is not set +CONFIG_LIBFDT=y +CONFIG_OID_REGISTRY=y +# CONFIG_SG_SPLIT is not set +CONFIG_ARCH_HAS_SG_CHAIN=y +# CONFIG_VIRTUALIZATION is not set diff --git a/packages/base/any/kernels/4.4-lts/kconfig.mk b/packages/base/any/kernels/4.4-lts/kconfig.mk new file mode 100644 index 00000000..4262cad1 --- /dev/null +++ b/packages/base/any/kernels/4.4-lts/kconfig.mk @@ -0,0 +1,26 @@ +############################################################ +# +# +# Copyright 2015 Big Switch Networks, Inc. +# +# Licensed under the Eclipse Public License, Version 1.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.eclipse.org/legal/epl-v10.html +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +# either express or implied. See the License for the specific +# language governing permissions and limitations under the +# License. +# +# +############################################################ +THIS_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) +K_MAJOR_VERSION := 4 +K_PATCH_LEVEL := 4 +K_SUB_LEVEL := 39 +K_SUFFIX := +K_PATCH_DIR := $(THIS_DIR)/patches diff --git a/packages/base/any/kernels/4.4-lts/patches/kernel-4.4-brcm-iproc.patch b/packages/base/any/kernels/4.4-lts/patches/kernel-4.4-brcm-iproc.patch new file mode 100644 index 00000000..4da5c804 --- /dev/null +++ b/packages/base/any/kernels/4.4-lts/patches/kernel-4.4-brcm-iproc.patch @@ -0,0 +1,75281 @@ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/Documentation/devicetree/bindings/gpio/xgs-gpio-iproc.txt b/Documentation/devicetree/bindings/gpio/xgs-gpio-iproc.txt +--- a/Documentation/devicetree/bindings/gpio/xgs-gpio-iproc.txt 1970-01-01 08:00:00.000000000 +0800 ++++ b/Documentation/devicetree/bindings/gpio/xgs-gpio-iproc.txt 2017-11-09 17:52:48.421892000 +0800 +@@ -0,0 +1,46 @@ ++Broadcom XGS iProc GPIO Controller ++ ++Required properties: ++- compatible : Should be "brcm,iproc-gpio,cca" or "brcm,iproc-gpio,ccg". ++ "brcm,iproc-gpio,cca" is used for CCA type gpio controllers on Helix4/Katana2/HR2. ++ "brcm,iproc-gpio,ccg" is used for CCG type gpio controllers on Grehound/Saber2/HR3/Greyhound2. ++- reg : Physical base address and length of the controller's registers. ++- #gpio-cells : should be 2 ++- ngpios : The number of GPIO's the controller provides. ++- interrupts : The interrupt id for the controller. ++- pin-base : The first chip GPIO pin provided by CCA or CCG. For Helix4, set to 4. ++- pin-offset : The offset of available CCA or CCG GPIO pins. For Helix4, set to 0. ++- gpio-controller : Marks the device node as a GPIO controller. ++ ++Optional properties: ++- interrupt-controller : Marks the device node as an interrupt controller. ++ ++ ++Examples for cca gpio: ++ ++ gpio_cca: gpio@18000060 { ++ compatible = "brcm,iproc-gpio,cca"; ++ #gpio-cells = <2>; ++ reg = gpio: <0x18000060 0x50>, ++ intr: <0x18000000 0x50>; ++ ngpios = <8>; ++ pin-offset = <0>; ++ pin-base = <4>; ++ gpio-controller; ++ interrupt-controller; ++ interrupts = ; ++ }; ++ ++ gpio_ccg: gpio@1800a000 { ++ compatible = "brcm,iproc-gpio,ccg"; ++ #gpio-cells = <2>; ++ reg = gpio: <0x1800a000 0x50>; ++ ngpios = <12>; ++ pin-offset = <4>; ++ pin-base = <4>; ++ gpio-controller; ++ interrupt-controller; ++ interrupts = ; ++ }; ++ ++ +\ No newline at end of file +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/Documentation/devicetree/bindings/net/xgs-iproc-mdio.txt b/Documentation/devicetree/bindings/net/xgs-iproc-mdio.txt +--- a/Documentation/devicetree/bindings/net/xgs-iproc-mdio.txt 1970-01-01 08:00:00.000000000 +0800 ++++ b/Documentation/devicetree/bindings/net/xgs-iproc-mdio.txt 2017-11-09 17:52:49.481900000 +0800 +@@ -0,0 +1,30 @@ ++* Broadcom XGS iProc MDIO bus controller ++ ++Required properties: ++- compatible: should be "brcm,iproc-ccb-mdio" or "brcm,iproc-ccg-mdio" or "brcm,iproc-cmicd-mdio" ++- reg: address and length of the register set for the MDIO interface ++- #size-cells: must be 0 ++- #address-cells: must be 1 ++- #bus-id: Physical bus ID ++- #logical-bus-id: Logical bus ID, required for cmicd ++- bus-type: "internal" or "external" ++- clocks: clock source ++ ++Example: ++ ++ mdio_int: mdio_int@18002000 { ++ compatible = "brcm,iproc-ccg-mdio"; ++ reg = <0x18002000 0x1000>; ++ #bus-id = <0>; ++ bus-type = "internal"; ++ clocks = <&iproc_apb_clk>; ++ }; ++ ++ mdio_ext: mdio_ext@03210000 { ++ compatible = "brcm,iproc-cmicd-mdio"; ++ reg = <0x03210000 0x1000>; ++ #bus-id = <2>; ++ #logical-bus-id = <0>; ++ bus-type = "external"; ++ clocks = <&iproc_apb_clk>; ++ }; +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/Documentation/devicetree/bindings/pci/xgs-iproc-pcie.txt b/Documentation/devicetree/bindings/pci/xgs-iproc-pcie.txt +--- a/Documentation/devicetree/bindings/pci/xgs-iproc-pcie.txt 1970-01-01 08:00:00.000000000 +0800 ++++ b/Documentation/devicetree/bindings/pci/xgs-iproc-pcie.txt 2017-11-09 17:52:49.540901000 +0800 +@@ -0,0 +1,35 @@ ++* Broadcom XGS iProc PCIe controller ++ ++Required properties: ++- compatible: set to "brcm,iproc-pcie" ++- reg: base address and length of the PCIe controller ++- linux,pci-domain: PCI domain ID. Should be unique for each host controller ++- interrupts: interrupt ID ++- #address-cells: set to <3> ++- #size-cells: set to <2> ++- device_type: set to "pci" ++- ranges: ranges for the PCI memory and I/O regions ++ ++Optional properties: ++- phy-addr: PCIe PHY addr for MDIO access ++- bus-range: PCI bus numbers covered ++ ++Example: ++ ++ pcie0: pcie@18012000 { ++ compatible = "brcm,iproc-pcie"; ++ reg = <0x18012000 0x1000>; ++ linux,pci-domain = <0>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ ; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ ranges = <0x82000000 0 0x20000000 0x20000000 0 0x20000000>; ++ phy-addr = <0>; ++ }; ++ +\ No newline at end of file +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/Documentation/devicetree/bindings/spi/xgs-iproc-qspi.txt b/Documentation/devicetree/bindings/spi/xgs-iproc-qspi.txt +--- a/Documentation/devicetree/bindings/spi/xgs-iproc-qspi.txt 1970-01-01 08:00:00.000000000 +0800 ++++ b/Documentation/devicetree/bindings/spi/xgs-iproc-qspi.txt 2017-11-09 17:52:50.501910000 +0800 +@@ -0,0 +1,34 @@ ++BROADCOM XGS iProc QSPI controller ++ ++Required properties: ++- compatible: "brcm,iproc-qspi"; ++- reg: Offset and length of the register set including ++ mspi_hw: Master SPI ++ bspi_hw: Boot SPI ++ bspi_hw_raf: Boot SPI read ahead fifo ++ qspi_intr: QSPI interrupt related ++ idm_qspi:QSPI IDM related ++ cru_hw: QSPI CRU related ++- interrupts: interrupt id of the QSPI controller ++- clocks: clock source ++ ++Optional properties: ++- #chip-select: Specify the used chip select for controller with multi chip selects ++ ++Example: ++ ++ qspi: spi@18047000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "brcm,iproc-qspi"; ++ reg = mspi_hw:<0x18047200 0x188>, ++ bspi_hw:<0x18047000 0x050>, ++ bspi_hw_raf:<0x18047100 0x024>, ++ qspi_intr:<0x180473a0 0x01c>, ++ idm_qspi:<0x1811f408 0x004>, ++ cru_hw:<0x1800e000 0x004>; ++ interrupts = ; ++ #chip-select = <0>; ++ clocks = <&iproc_apb_clk>; ++ }; ++ +\ No newline at end of file +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/Kconfig b/arch/arm/Kconfig +--- a/arch/arm/Kconfig 2016-12-16 00:49:34.000000000 +0800 ++++ b/arch/arm/Kconfig 2017-11-09 17:52:54.375925000 +0800 +@@ -850,6 +850,8 @@ source "arch/arm/mach-iop33x/Kconfig" + + source "arch/arm/mach-iop13xx/Kconfig" + ++source "arch/arm/mach-iproc/Kconfig" ++ + source "arch/arm/mach-ixp4xx/Kconfig" + + source "arch/arm/mach-keystone/Kconfig" +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/Makefile b/arch/arm/Makefile +--- a/arch/arm/Makefile 2016-12-16 00:49:34.000000000 +0800 ++++ b/arch/arm/Makefile 2017-11-09 17:52:54.385925000 +0800 +@@ -176,6 +176,7 @@ machine-$(CONFIG_ARCH_INTEGRATOR) += int + machine-$(CONFIG_ARCH_IOP13XX) += iop13xx + machine-$(CONFIG_ARCH_IOP32X) += iop32x + machine-$(CONFIG_ARCH_IOP33X) += iop33x ++machine-$(CONFIG_ARCH_XGS_IPROC) += iproc + machine-$(CONFIG_ARCH_IXP4XX) += ixp4xx + machine-$(CONFIG_ARCH_KEYSTONE) += keystone + machine-$(CONFIG_ARCH_KS8695) += ks8695 +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile +--- a/arch/arm/boot/dts/Makefile 2016-12-16 00:49:34.000000000 +0800 ++++ b/arch/arm/boot/dts/Makefile 2017-11-09 17:52:54.462930000 +0800 +@@ -777,6 +777,17 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ + mt8127-moose.dtb \ + mt8135-evbp1.dtb + dtb-$(CONFIG_ARCH_ZX) += zx296702-ad1.dtb ++ ++dtb-$(CONFIG_MACH_HX4) += bcm956340.dtb ++dtb-$(CONFIG_MACH_KT2) += bcm956450.dtb ++dtb-$(CONFIG_MACH_HR2) += bcm956150.dtb ++dtb-$(CONFIG_MACH_GH) += bcm95341x.dtb ++dtb-$(CONFIG_MACH_GH2) += bcm956170.dtb bcm95357x.dtb ++dtb-$(CONFIG_MACH_SB2) += bcm956260.dtb ++dtb-$(CONFIG_MACH_WH2) += bcm953547.dtb ++dtb-$(CONFIG_MACH_HR3) += bcm956160.dtb \ ++ bcm953444.dtb ++ + endif + + dtstree := $(srctree)/$(src) +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm-greyhound.dtsi b/arch/arm/boot/dts/bcm-greyhound.dtsi +--- a/arch/arm/boot/dts/bcm-greyhound.dtsi 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm-greyhound.dtsi 2017-11-09 17:52:54.682932000 +0800 +@@ -0,0 +1,362 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++#include "skeleton.dtsi" ++ ++ ++/ { ++ model = "Broadcom GH iProc"; ++ compatible = "brcm,greyhound"; ++ interrupt-parent = <&gic>; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a9"; ++ next-level-cache = <&L2>; ++ reg = <0x0>; ++ }; ++ }; ++ ++ core { ++ compatible = "simple-bus"; ++ ranges = <0x00000000 0x19000000 0x00023000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ a9pll: arm_clk@00000 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-armpll"; ++ clocks = <&osc>; ++ reg = <0x0 0x1000>; ++ }; ++ ++ gic: interrupt-controller@21000 { ++ compatible = "arm,cortex-a9-gic"; ++ #interrupt-cells = <3>; ++ interrupt-controller; ++ reg = <0x21000 0x1000>, <0x20100 0x100>; ++ }; ++ ++ twd-timer@20600 { ++ compatible = "arm,cortex-a9-twd-timer"; ++ reg = <0x20600 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ timer@20200 { ++ compatible = "arm,cortex-a9-global-timer"; ++ reg = <0x20200 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ L2: l2-cache { ++ compatible = "arm,pl310-cache"; ++ reg = <0x22000 0x1000>; ++ cache-unified; ++ cache-level = <2>; ++ arm,filter-ranges = <0x60000000 0x80000000>; ++ }; ++ }; ++ ++ clocks { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ osc: oscillator { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <25000000>; ++ }; ++ ++ periph_clk: periph_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&a9pll>; ++ clock-div = <2>; ++ clock-mult = <1>; ++ }; ++ ++ iproc_axi_clk: iproc_axi_clk@0x1800fc00 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-axi-clk"; ++ clocks = <&osc>; ++ reg = <0x1800fc00 0x1c>; ++ }; ++ ++ iproc_apb_clk: iproc_apb_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&iproc_axi_clk>; ++ clock-div = <4>; ++ clock-mult = <1>; ++ }; ++ }; ++ ++ axi { ++ compatible = "simple-bus"; ++ ranges; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ uart0: serial@18020000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x18020000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ uart1: serial@18021000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x18021000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ gmac0: ethernet@18042000 { ++ compatible = "brcm,iproc-gmac"; ++ reg = <0x18042000 0x1000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ gpio_ccg: gpio@1800a000 { ++ compatible = "brcm,iproc-gpio,ccg"; ++ #gpio-cells = <2>; ++ reg = gpio: <0x1800a000 0x50>; ++ ngpios = <12>; ++ pin-offset = <4>; ++ pin-base = <4>; ++ gpio-controller; ++ interrupt-controller; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ usbphy0: usbphy0 { ++ #phy-cells = <0>; ++ compatible = "brcm,usb-phy,gh"; ++ reg = idm_usb2h: <0x18115000 0x1000>, ++ idm_usb2d: <0x18111000 0x1000>; ++ vbus-gpio = <&gpio_ccg 6 GPIO_ACTIVE_HIGH>; ++ status = "disabled"; ++ }; ++ ++ ehci0: usb@18048000 { ++ compatible = "generic-ehci"; ++ reg = <0x18048000 0x800>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ ohci0: usb@18048800 { ++ compatible = "generic-ohci"; ++ reg = <0x18048800 0x800>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ usbd: usbd@1804c000 { ++ compatible = "brcm,usbd,gh"; ++ reg = <0x1804c000 0x2000>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ nand: nand@18046000 { ++ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; ++ reg = <0x18046000 0x600>, ++ <0xf8105408 0x10>, ++ <0x18046f00 0x20>; ++ reg-names = "nand", "iproc-idm", "iproc-ext"; ++ interrupts = ; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ brcm,nand-has-wp; ++ status = "disabled"; ++ }; ++ ++ qspi: spi@18047000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "brcm,iproc-qspi"; ++ reg = mspi_hw:<0x18047200 0x188>, ++ bspi_hw:<0x18047000 0x050>, ++ bspi_hw_raf:<0x18047100 0x024>, ++ qspi_intr:<0x180473a0 0x01c>, ++ idm_qspi:<0xf8106408 0x004>, ++ cru_hw:<0x1800e000 0x004>; ++ interrupts = ; ++ #chip-select = <0>; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ i2c0: i2c@18008000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x18008000 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ mdio_int: mdio_int@18002000 { ++ compatible = "brcm,iproc-ccg-mdio"; ++ reg = <0x18002000 0x1000>; ++ #bus-id = <0>; ++ bus-type = "internal"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd cmic_common mdio */ ++ mdio_ext: mdio_ext@03210000 { ++ compatible = "brcm,iproc-cmicd-mdio"; ++ reg = <0x03210000 0x1000>; ++ #bus-id = <2>; ++ #logical-bus-id = <0>; ++ bus-type = "external"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ pnor_flash: pnor_flash@18045000 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "brcm,iproc-nor"; ++ reg = nor_regs: <0x18045000 0x1000>, ++ nor_mem: <0xE8000000 0x8000000>, ++ nor_sel: <0x18000c8c 0x4>, ++ nor_strap: <0x18000a5c 0x4>; ++ status = "disabled"; ++ }; ++ ++ hwrng: hwrng@18032000 { ++ compatible = "brcm,iproc-rng"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x18032000 0x1000>; ++ rng-type = "rng200"; ++ status = "disabled"; ++ }; ++ ++ iproc_wdt: iproc_wdt@18009000 { ++ compatible = "arm,sp805", "arm,primecell"; ++ reg = iproc_wdt_base: <0x18009000 0x1000>, ++ iproc_reset_reg: <0x1800f014 0x4>; ++ wdt_boot_status_bit = <0x0>; ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ /* cmicd */ ++ iproc_cmicd: iproc_cmicd@03200000 { ++ compatible = "brcm,iproc-cmicd"; ++ reg = <0x03200000 0x100000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ }; ++ ++ pcie0: pcie@18012000 { ++ compatible = "brcm,iproc-pcie", "iproc-p7"; ++ reg = <0x18012000 0x1000>; ++ linux,pci-domain = <0>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ ; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ /*non-prefetchable mem space, pcie addr 0x0 0x20000000, ++ * cpu addr 0x20000000, size 0x0 0x20000000 ++ */ ++ ranges = <0x82000000 0 0x20000000 0x20000000 0 0x20000000>; ++ phy-addr = <0>; ++ status = "disabled"; ++ }; ++ ++ dmu_pcu: dmu_pcu@1800f000 { ++ compatible = "brcm,iproc-dmu-pcu"; ++ reg = <0x1800f000 0xc00>; ++ }; ++ ++ iproc_wrap_ctrl: iproc_wrap_ctrl@1800fc00 { ++ compatible = "brcm,iproc-wrap-ctrl"; ++ reg = <0x1800fc00 0x100>; ++ }; ++ ++ iproc_idm: iproc_idm@18100000 { ++ compatible = "brcm,iproc-idm"; ++ reg = idm0: <0x18100000 0x100000>, ++ idm1: <0xf8100000 0x100000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ }; ++}; +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm-greyhound2.dtsi b/arch/arm/boot/dts/bcm-greyhound2.dtsi +--- a/arch/arm/boot/dts/bcm-greyhound2.dtsi 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm-greyhound2.dtsi 2017-11-09 17:52:54.683934000 +0800 +@@ -0,0 +1,415 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++#include "skeleton.dtsi" ++ ++ ++/ { ++ model = "Broadcom GH2 iProc"; ++ compatible = "brcm,greyhound2"; ++ interrupt-parent = <&gic>; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a9"; ++ next-level-cache = <&L2>; ++ reg = <0x0>; ++ }; ++ }; ++ ++ core { ++ compatible = "simple-bus"; ++ ranges = <0x00000000 0x19000000 0x00023000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ a9pll: arm_clk@00000 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-armpll"; ++ clocks = <&osc>; ++ reg = <0x0 0x1000>; ++ }; ++ ++ gic: interrupt-controller@21000 { ++ compatible = "arm,cortex-a9-gic"; ++ #interrupt-cells = <3>; ++ interrupt-controller; ++ reg = <0x21000 0x1000>, <0x20100 0x100>; ++ }; ++ ++ twd-timer@20600 { ++ compatible = "arm,cortex-a9-twd-timer"; ++ reg = <0x20600 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ timer@20200 { ++ compatible = "arm,cortex-a9-global-timer"; ++ reg = <0x20200 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ L2: l2-cache { ++ compatible = "arm,pl310-cache"; ++ reg = <0x22000 0x1000>; ++ cache-unified; ++ cache-level = <2>; ++ arm,filter-ranges = <0x60000000 0x80000000>; ++ }; ++ }; ++ ++ clocks { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ osc: oscillator { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <25000000>; ++ }; ++ ++ periph_clk: periph_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&a9pll>; ++ clock-div = <2>; ++ clock-mult = <1>; ++ }; ++ ++ iproc_axi_clk: iproc_axi_clk@0x1800fc00 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-axi-clk"; ++ clocks = <&osc>; ++ reg = <0x1800fc00 0x1c>; ++ }; ++ ++ iproc_apb_clk: iproc_apb_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&iproc_axi_clk>; ++ clock-div = <4>; ++ clock-mult = <1>; ++ }; ++ }; ++ ++ axi { ++ compatible = "simple-bus"; ++ ranges; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ uart0: serial@18020000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x18020000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ uart1: serial@18021000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x18021000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ gmac0: ethernet@18042000 { ++ compatible = "brcm,iproc-gmac"; ++ reg = <0x18042000 0x1000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ gmac1: ethernet@1804a000 { ++ compatible = "brcm,iproc-gmac"; ++ reg = <0x1804a000 0x1000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ gpio_ccg: gpio@1800a000 { ++ compatible = "brcm,iproc-gpio,ccg"; ++ #gpio-cells = <2>; ++ reg = gpio: <0x1800a000 0x50>; ++ ngpios = <12>; ++ pin-offset = <4>; ++ pin-base = <4>; ++ gpio-controller; ++ interrupt-controller; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ usbphy0: usbphy0 { ++ #phy-cells = <0>; ++ compatible = "brcm,usb-phy,gh"; ++ reg = idm_usb2h: <0x18115000 0x1000>, ++ idm_usb2d: <0x18111000 0x1000>, ++ idm_utmih: <0x18049500 0x100>; ++ vbus-gpio = <&gpio_ccg 6 GPIO_ACTIVE_HIGH>; ++ status = "disabled"; ++ }; ++ ++ ehci0: usb@18048000 { ++ compatible = "generic-ehci"; ++ reg = <0x18048000 0x800>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ ohci0: usb@18048800 { ++ compatible = "generic-ohci"; ++ reg = <0x18048800 0x800>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ usbd: usbd@1804c000 { ++ compatible = "brcm,usbd,gh"; ++ reg = <0x1804c000 0x2000>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ nand: nand@18046000 { ++ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; ++ reg = <0x18046000 0x600>, ++ <0xf8105408 0x10>, ++ <0x18046f00 0x20>; ++ reg-names = "nand", "iproc-idm", "iproc-ext"; ++ interrupts = ; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ brcm,nand-has-wp; ++ status = "disabled"; ++ }; ++ ++ qspi: spi@18047000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "brcm,iproc-qspi"; ++ reg = mspi_hw:<0x18047200 0x188>, ++ bspi_hw:<0x18047000 0x050>, ++ bspi_hw_raf:<0x18047100 0x024>, ++ qspi_intr:<0x180473a0 0x01c>, ++ idm_qspi:<0xf8106408 0x004>, ++ cru_hw:<0x1800e000 0x004>; ++ interrupts = ; ++ #chip-select = <0>; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ i2c0: i2c@18008000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x18008000 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ ccg_mdio_int: ccg_mdio_int@18002000 { ++ compatible = "brcm,iproc-ccg-mdio"; ++ reg = <0x18002000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #bus-id = <0>; ++ bus-type = "internal"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd cmic_common mdio */ ++ mdio_int: mdio_int@03210000 { ++ compatible = "brcm,iproc-cmicd-mdio"; ++ reg = <0x03210000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #bus-id = <0>; ++ #logical-bus-id = <1>; ++ bus-type = "internal"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd cmic_common mdio */ ++ mdio_ext: mdio_ext@03210000 { ++ compatible = "brcm,iproc-cmicd-mdio"; ++ reg = <0x03210000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #bus-id = <2>; ++ #logical-bus-id = <0>; ++ bus-type = "external"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ pnor_flash: pnor_flash@18045000 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "brcm,iproc-nor"; ++ reg = nor_regs: <0x18045000 0x1000>, ++ nor_mem: <0xE8000000 0x8000000>, ++ nor_sel: <0x18000c8c 0x4>, ++ nor_strap: <0x18000a5c 0x4>; ++ status = "disabled"; ++ }; ++ ++ hwrng: hwrng@18032000 { ++ compatible = "brcm,iproc-rng"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x18032000 0x1000>; ++ rng-type = "rng200"; ++ status = "disabled"; ++ }; ++ ++ iproc_wdt: iproc_wdt@18009000 { ++ compatible = "arm,sp805", "arm,primecell"; ++ reg = iproc_wdt_base: <0x18009000 0x1000>, ++ iproc_reset_reg: <0x1800f014 0x4>; ++ wdt_boot_status_bit = <0x0>; ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ dmac0: dma@18018000 { ++ compatible = "brcm,dma330", "arm,primecell"; ++ reg = dma330_base: <0x18018000 0x1000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ #dma-cells = <1>; ++ #dma-channels = <8>; ++ #dma-requests = <16>; ++ status = "disabled"; ++ }; ++ ++ crypto: crypto@03100000 { ++ compatible = "brcm,iproc-crypto"; ++ reg = axi: <0x03100000 0x100>, /* SPUM AXI registers */ ++ apb: <0x18037000 0x100>, /* SPUM control registers */ ++ idm: <0x1811a000 0x1000>; /* Crypto control registers */ ++ brcm,max-pkt-size = <65536>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd */ ++ iproc_cmicd: iproc_cmicd@03200000 { ++ compatible = "brcm,iproc-cmicd"; ++ reg = <0x03200000 0x100000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ }; ++ ++ pcie0: pcie@18012000 { ++ compatible = "brcm,iproc-pcie", "iproc-p7"; ++ reg = <0x18012000 0x1000>; ++ linux,pci-domain = <0>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ ; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ /*non-prefetchable mem space, pcie addr 0x0 0x20000000, ++ * cpu addr 0x20000000, size 0x0 0x20000000 ++ */ ++ ranges = <0x82000000 0 0x20000000 0x20000000 0 0x20000000>; ++ phy-addr = <0>; ++ status = "disabled"; ++ }; ++ ++ dmu_pcu: dmu_pcu@1800f000 { ++ compatible = "brcm,iproc-dmu-pcu"; ++ reg = <0x1800f000 0xc00>; ++ }; ++ ++ iproc_wrap_ctrl: iproc_wrap_ctrl@1800fc00 { ++ compatible = "brcm,iproc-wrap-ctrl"; ++ reg = <0x1800fc00 0x100>; ++ }; ++ ++ iproc_idm: iproc_idm@18100000 { ++ compatible = "brcm,iproc-idm"; ++ reg = idm0: <0x18100000 0x100000>, ++ idm1: <0xf8100000 0x100000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ }; ++}; +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm-helix4.dtsi b/arch/arm/boot/dts/bcm-helix4.dtsi +--- a/arch/arm/boot/dts/bcm-helix4.dtsi 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm-helix4.dtsi 2017-11-09 17:52:54.684933000 +0800 +@@ -0,0 +1,434 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++#include "skeleton.dtsi" ++ ++ ++/ { ++ model = "Broadcom HX4 iProc"; ++ compatible = "brcm,helix4"; ++ interrupt-parent = <&gic>; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cpu0: cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a9"; ++ next-level-cache = <&L2>; ++ reg = <0x0>; ++ }; ++ ++ cpu1: cpu@1 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a9"; ++ next-level-cache = <&L2>; ++ enable-method = "brcm,bcm-nsp-smp"; ++ secondary-boot-reg = <0xffff042c>; ++ reg = <0x1>; ++ }; ++ }; ++ ++ mpcore { ++ compatible = "simple-bus"; ++ ranges = <0x00000000 0x19000000 0x00023000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ a9pll: arm_clk@00000 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-armpll"; ++ clocks = <&osc>; ++ reg = <0x0 0x1000>; ++ }; ++ ++ gic: interrupt-controller@21000 { ++ compatible = "arm,cortex-a9-gic"; ++ #interrupt-cells = <3>; ++ interrupt-controller; ++ reg = <0x21000 0x1000>, <0x20100 0x100>; ++ }; ++ ++ twd-timer@20600 { ++ compatible = "arm,cortex-a9-twd-timer"; ++ reg = <0x20600 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ timer@20200 { ++ compatible = "arm,cortex-a9-global-timer"; ++ reg = <0x20200 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ L2: l2-cache { ++ compatible = "arm,pl310-cache"; ++ reg = <0x22000 0x1000>; ++ cache-unified; ++ cache-level = <2>; ++ arm,filter-ranges = <0x60000000 0x80000000>; ++ /*arm,parity-enable = <1>; ++ interrupts = ;*/ ++ }; ++ }; ++ ++ clocks { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ osc: oscillator { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <25000000>; ++ }; ++ ++ periph_clk: periph_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&a9pll>; ++ clock-div = <2>; ++ clock-mult = <1>; ++ }; ++ ++ iproc_axi_clk: iproc_axi_clk@0x1803fc00 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-axi-clk", "axi-clk-hx4"; ++ clocks = <&osc>; ++ reg = <0x1803fc00 0x1c>; ++ }; ++ ++ iproc_apb_clk: iproc_apb_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&iproc_axi_clk>; ++ clock-div = <4>; ++ clock-mult = <1>; ++ }; ++ }; ++ ++ axi { ++ compatible = "simple-bus"; ++ ranges; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ uart0: serial@18000300 { ++ compatible = "ns16550a"; ++ reg = <0x18000300 0x100>; ++ interrupts = ; ++ clock-frequency = <62500000>; ++ status = "disabled"; ++ }; ++ ++ uart1: serial@18000400 { ++ compatible = "ns16550a"; ++ reg = <0x18000400 0x100>; ++ interrupts = ; ++ clock-frequency = <62500000>; ++ status = "disabled"; ++ }; ++ ++ uart2: serial@18037000 { ++ compatible = "ns16550a"; ++ reg = <0x18037000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_cca: gpio@18000060 { ++ compatible = "brcm,iproc-gpio,cca"; ++ #gpio-cells = <2>; ++ reg = gpio: <0x18000060 0x50>, ++ intr: <0x18000000 0x50>; ++ ngpios = <8>; ++ pin-offset = <0>; ++ pin-base = <4>; ++ gpio-controller; ++ interrupt-controller; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ gmac0: ethernet@18022000 { ++ compatible = "brcm,iproc-gmac"; ++ reg = <0x18022000 0x1000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ gmac1: ethernet@18023000 { ++ compatible = "brcm,iproc-gmac"; ++ reg = <0x18023000 0x1000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ nand: nand@18026000 { ++ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; ++ reg = <0x18026000 0x600>, ++ <0x1811b408 0x10>, ++ <0x18026f00 0x20>; ++ reg-names = "nand", "iproc-idm", "iproc-ext"; ++ interrupts = ; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ brcm,nand-has-wp; ++ }; ++ ++ qspi: spi@18027000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "brcm,iproc-qspi"; ++ reg = mspi_hw:<0x18027200 0x188>, ++ bspi_hw:<0x18027000 0x050>, ++ bspi_hw_raf:<0x18027100 0x024>, ++ qspi_intr:<0x180273a0 0x01c>, ++ idm_qspi:<0x1811c408 0x004>, ++ cru_hw:<0x1803e000 0x004>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ ; ++ #chip-select = <0>; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ usbphy0: usbphy0 { ++ #phy-cells = <0>; ++ compatible = "brcm,usb-phy,hx4"; ++ reg = idm_usb2h: <0x18115000 0x1000>, ++ idm_usb2d: <0x18116000 0x1000>; ++ vbus-gpio = <&gpio_cca 1 GPIO_ACTIVE_LOW>; ++ usbdev-gpio = <&gpio_cca 0 GPIO_ACTIVE_HIGH>; ++ status = "disabled"; ++ }; ++ ++ ehci0: usb@1802a000 { ++ compatible = "generic-ehci"; ++ reg = <0x1802a000 0x1000>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ usbd: usbd@18042000 { ++ compatible = "brcm,usbd,hx4"; ++ reg = <0x18042000 0x2000>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ i2c0: i2c@18038000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x18038000 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ i2c1: i2c@1803b000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x1803b000 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ mdio_int: mdio_int@18032000 { ++ compatible = "brcm,iproc-ccb-mdio"; ++ reg = <0x18032000 0x1000>; ++ #bus-id = <0>; ++ bus-type = "internal"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ mdio_ext: mdio_ext@18032000 { ++ compatible = "brcm,iproc-ccb-mdio"; ++ reg = <0x18032000 0x1000>; ++ #bus-id = <0>; ++ bus-type = "external"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ hwrng: hwrng@18033000 { ++ compatible = "brcm,iproc-rng"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x18033000 0x1000>; ++ rng-type = "rng"; ++ status = "disabled"; ++ }; ++ ++ iproc_wdt: iproc_wdt@0x18039000 { ++ compatible = "arm,sp805", "arm,primecell"; ++ reg = iproc_wdt_base: <0x18039000 0x1000>, ++ iproc_reset_reg: <0x1803f014 0x4>; ++ wdt_boot_status_bit = <0x0>; ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ dmac0: dma@18020000 { ++ compatible = "arm,pl330", "arm,primecell"; ++ reg = pl330_base: <0x18020000 0x1000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ /*arm,primecell-periphid = <0x00041330>;*/ ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ #dma-cells = <1>; ++ #dma-channels = <8>; ++ #dma-requests = <16>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd */ ++ iproc_cmicd: iproc_cmicd@48000000 { ++ compatible = "brcm,iproc-cmicd"; ++ reg = <0x48000000 0x40000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ }; ++ ++ pcie0: pcie@18012000 { ++ compatible = "brcm,iproc-pcie", "iproc-p2"; ++ reg = <0x18012000 0x1000>; ++ linux,pci-domain = <0>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ ; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ /*non-prefetchable mem space, pcie addr 0x0 0x08000000, ++ * cpu addr 0x08000000, size 0x0 0x08000000 ++ */ ++ ranges = <0x82000000 0 0x08000000 0x08000000 0 0x08000000>; ++ phy-addr = <0>; ++ status = "disabled"; ++ }; ++ ++ pcie1: pcie@18013000 { ++ compatible = "brcm,iproc-pcie", "iproc-p2"; ++ reg = <0x18013000 0x1000>; ++ linux,pci-domain = <1>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ ; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ /*non-prefetchable mem space, pcie addr 0x0 0x40000000, ++ * cpu addr 0x40000000, size 0x0 0x08000000 ++ */ ++ ranges = <0x82000000 0 0x40000000 0x40000000 0 0x08000000>; ++ phy-addr = <1>; ++ status = "disabled"; ++ }; ++ ++ dmu_pcu: dmu_pcu@1803f000 { ++ compatible = "brcm,iproc-dmu-pcu"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x1803f000 0xc00>; ++ }; ++ ++ iproc_wrap_ctrl: iproc_wrap_ctrl@1803fc00 { ++ compatible = "brcm,iproc-wrap-ctrl"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x1803fc00 0x100>; ++ }; ++ ++ iproc_idm: iproc_idm@18100000 { ++ compatible = "brcm,iproc-idm"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x18100000 0x100000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ }; ++}; +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm-hurricane2.dtsi b/arch/arm/boot/dts/bcm-hurricane2.dtsi +--- a/arch/arm/boot/dts/bcm-hurricane2.dtsi 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm-hurricane2.dtsi 2017-11-09 17:52:54.685935000 +0800 +@@ -0,0 +1,314 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include "skeleton.dtsi" ++ ++ ++/ { ++ model = "Broadcom HR2 iProc"; ++ compatible = "brcm,hurricane2"; ++ interrupt-parent = <&gic>; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a9"; ++ next-level-cache = <&L2>; ++ reg = <0x0>; ++ }; ++ }; ++ ++ core { ++ compatible = "simple-bus"; ++ ranges = <0x00000000 0x19000000 0x00023000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ a9pll: arm_clk@00000 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-armpll"; ++ clocks = <&osc>; ++ reg = <0x0 0x1000>; ++ }; ++ ++ gic: interrupt-controller@21000 { ++ compatible = "arm,cortex-a9-gic"; ++ #interrupt-cells = <3>; ++ interrupt-controller; ++ reg = <0x21000 0x1000>, <0x20100 0x100>; ++ }; ++ ++ twd-timer@20600 { ++ compatible = "arm,cortex-a9-twd-timer"; ++ reg = <0x20600 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ timer@20200 { ++ compatible = "arm,cortex-a9-global-timer"; ++ reg = <0x20200 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ L2: l2-cache { ++ compatible = "arm,pl310-cache"; ++ reg = <0x22000 0x1000>; ++ cache-unified; ++ cache-level = <2>; ++ arm,filter-ranges = <0x60000000 0x80000000>; ++ }; ++ }; ++ ++ clocks { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ osc: oscillator { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <25000000>; ++ }; ++ ++ periph_clk: periph_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&a9pll>; ++ clock-div = <2>; ++ clock-mult = <1>; ++ }; ++ ++ iproc_axi_clk: iproc_axi_clk@1803fc00 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-axi-clk", "axi-clk-hr2"; ++ clocks = <&osc>; ++ reg = <0x1803fc00 0x1c>; ++ }; ++ ++ iproc_apb_clk: iproc_apb_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&iproc_axi_clk>; ++ clock-div = <4>; ++ clock-mult = <1>; ++ }; ++ }; ++ ++ axi { ++ compatible = "simple-bus"; ++ ranges; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ uart0: serial@18000300 { ++ compatible = "ns16550a"; ++ reg = <0x18000300 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ uart1: serial@18000400 { ++ compatible = "ns16550a"; ++ reg = <0x18000400 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ gpio_cca: gpio@18000060 { ++ compatible = "brcm,iproc-gpio,cca"; ++ #gpio-cells = <2>; ++ reg = gpio: <0x18000060 0x50>, ++ intr: <0x18000000 0x50>, ++ dmu: <0x18020000 0x200>; ++ ngpios = <12>; ++ pin-offset = <0>; ++ pin-base = <4>; ++ gpio-controller; ++ interrupt-controller; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ gmac0: ethernet@18022000 { ++ compatible = "brcm,iproc-gmac"; ++ reg = <0x18022000 0x1000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ nand: nand@18026000 { ++ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; ++ reg = <0x18026000 0x600>, ++ <0x1811b408 0x10>, ++ <0x18026f00 0x20>; ++ reg-names = "nand", "iproc-idm", "iproc-ext"; ++ interrupts = ; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ brcm,nand-has-wp; ++ status = "disabled"; ++ }; ++ ++ qspi: spi@18027000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "brcm,iproc-qspi"; ++ reg = mspi_hw:<0x18027200 0x188>, ++ bspi_hw:<0x18027000 0x050>, ++ bspi_hw_raf:<0x18027100 0x024>, ++ qspi_intr:<0x180273a0 0x01c>, ++ idm_qspi:<0x1811c408 0x004>, ++ cru_hw:<0x1803e000 0x004>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ ; ++ #chip-select = <0>; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ mdio_int: mdio_int@18032000 { ++ compatible = "brcm,iproc-ccb-mdio"; ++ reg = <0x18032000 0x1000>; ++ #bus-id = <0>; ++ bus-type = "internal"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ mdio_ext: mdio_ext@18032000 { ++ compatible = "brcm,iproc-ccb-mdio"; ++ reg = <0x18032000 0x1000>; ++ #bus-id = <0>; ++ bus-type = "external"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ pnor_flash: pnor_flash@18021000 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "brcm,iproc-nor"; ++ reg = nor_regs: <0x18021000 0x1000>, ++ nor_mem: <0x20000000 0x4000000>, ++ nor_sel: <0x1803fc3c 0x4>; ++ status = "disabled"; ++ }; ++ ++ iproc_wdt: iproc_wdt@18039000 { ++ compatible = "arm,sp805", "arm,primecell"; ++ reg = iproc_wdt_base: <0x18039000 0x1000>, ++ iproc_reset_reg: <0x1803f014 0x4>; ++ wdt_boot_status_bit = <0x0>; ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ /* cmicd */ ++ iproc_cmicd: iproc_cmicd@48000000 { ++ compatible = "brcm,iproc-cmicd"; ++ reg = <0x48000000 0x40000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ }; ++ ++ pcie0: pcie@18012000 { ++ compatible = "brcm,iproc-pcie", "iproc-p2"; ++ reg = <0x18012000 0x1000>; ++ linux,pci-domain = <0>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ ; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ /*non-prefetchable mem space, pcie addr 0x0 0x08000000, ++ * cpu addr 0x08000000, size 0x0 0x08000000 ++ */ ++ ranges = <0x82000000 0 0x08000000 0x08000000 0 0x08000000>; ++ phy-addr = <0>; ++ status = "disabled"; ++ }; ++ ++ dmu_pcu: dmu_pcu@1803f000 { ++ compatible = "brcm,iproc-dmu-pcu"; ++ reg = <0x1803f000 0xc00>; ++ }; ++ ++ iproc_wrap_ctrl: iproc_wrap_ctrl@1803fc00 { ++ compatible = "brcm,iproc-wrap-ctrl"; ++ reg = <0x1803fc00 0x100>; ++ }; ++ ++ iproc_idm: iproc_idm@18100000 { ++ compatible = "brcm,iproc-idm"; ++ reg = <0x18100000 0x100000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ }; ++}; +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm-hurricane3.dtsi b/arch/arm/boot/dts/bcm-hurricane3.dtsi +--- a/arch/arm/boot/dts/bcm-hurricane3.dtsi 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm-hurricane3.dtsi 2017-11-09 17:52:54.686936000 +0800 +@@ -0,0 +1,369 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++#include "skeleton.dtsi" ++ ++ ++/ { ++ model = "Broadcom HR3 iProc"; ++ compatible = "brcm,hurricane3"; ++ interrupt-parent = <&gic>; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a9"; ++ next-level-cache = <&L2>; ++ reg = <0x0>; ++ }; ++ }; ++ ++ core { ++ compatible = "simple-bus"; ++ ranges = <0x00000000 0x19000000 0x00023000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ a9pll: arm_clk@00000 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-armpll"; ++ clocks = <&osc>; ++ reg = <0x0 0x1000>; ++ }; ++ ++ gic: interrupt-controller@21000 { ++ compatible = "arm,cortex-a9-gic"; ++ #interrupt-cells = <3>; ++ interrupt-controller; ++ reg = <0x21000 0x1000>, <0x20100 0x100>; ++ }; ++ ++ twd-timer@20600 { ++ compatible = "arm,cortex-a9-twd-timer"; ++ reg = <0x20600 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ timer@20200 { ++ compatible = "arm,cortex-a9-global-timer"; ++ reg = <0x20200 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ L2: l2-cache { ++ compatible = "arm,pl310-cache"; ++ reg = <0x22000 0x1000>; ++ cache-unified; ++ cache-level = <2>; ++ arm,filter-ranges = <0x60000000 0x80000000>; ++ }; ++ }; ++ ++ clocks { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ osc: oscillator { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <25000000>; ++ }; ++ ++ periph_clk: periph_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&a9pll>; ++ clock-div = <2>; ++ clock-mult = <1>; ++ }; ++ ++ iproc_axi_clk: iproc_axi_clk@1800fc00 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-axi-clk"; ++ clocks = <&osc>; ++ reg = <0x1800fc00 0x1c>; ++ }; ++ ++ iproc_apb_clk: iproc_apb_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&iproc_axi_clk>; ++ clock-div = <4>; ++ clock-mult = <1>; ++ }; ++ }; ++ ++ axi { ++ compatible = "simple-bus"; ++ ranges; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ uart0: serial@18020000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x18020000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ uart1: serial@18021000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x18021000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ gmac0: ethernet@18042000 { ++ compatible = "brcm,iproc-gmac"; ++ reg = <0x18042000 0x1000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ gpio_ccg: gpio@1800a000 { ++ compatible = "brcm,iproc-gpio,ccg"; ++ #gpio-cells = <2>; ++ reg = gpio: <0x1800a000 0x50>; ++ ngpios = <12>; ++ pin-offset = <4>; ++ pin-base = <4>; ++ gpio-controller; ++ interrupt-controller; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ usbphy0: usbphy0 { ++ #phy-cells = <0>; ++ compatible = "brcm,usb-phy,gh"; ++ reg = idm_usb2h: <0x18115000 0x1000>, ++ idm_usb2d: <0x18111000 0x1000>; ++ vbus-gpio = <&gpio_ccg 3 GPIO_ACTIVE_HIGH>; ++ status = "disabled"; ++ }; ++ ++ ehci0: usb@0x18048000 { ++ compatible = "generic-ehci"; ++ reg = <0x18048000 0x800>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ ohci0: usb@0x18048800 { ++ compatible = "generic-ohci"; ++ reg = <0x18048800 0x800>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ usbd: usbd@1804c000 { ++ compatible = "brcm,usbd,hr3"; ++ reg = <0x1804c000 0x2000>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ sdio: sdio@18041000 { ++ compatible = "brcm,iproc-hr3-sdio"; ++ reg = <0x18041000 0x1000>, ++ <0x18116408 0x1000>; ++ reg-names = "sdio", "iproc-idm"; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ nand: nand@18046000 { ++ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; ++ reg = <0x18046000 0x600>, ++ <0x1811d408 0x10>, ++ <0x18046f00 0x20>; ++ reg-names = "nand", "iproc-idm", "iproc-ext"; ++ interrupts = ; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ brcm,nand-has-wp; ++ status = "disabled"; ++ }; ++ ++ qspi: spi@18047000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "brcm,iproc-qspi"; ++ reg = mspi_hw:<0x18047200 0x188>, ++ bspi_hw:<0x18047000 0x050>, ++ bspi_hw_raf:<0x18047100 0x024>, ++ qspi_intr:<0x180473a0 0x01c>, ++ idm_qspi:<0x1811f408 0x004>, ++ cru_hw:<0x1800e000 0x004>; ++ interrupts = ; ++ #chip-select = <0>; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ i2c0: i2c@18008000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x18008000 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ mdio_int: mdio_int@18002000 { ++ compatible = "brcm,iproc-ccg-mdio"; ++ reg = <0x18002000 0x1000>; ++ #bus-id = <0>; ++ bus-type = "internal"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd cmic_common mdio */ ++ mdio_ext: mdio_ext@03210000 { ++ compatible = "brcm,iproc-cmicd-mdio"; ++ reg = <0x03210000 0x1000>; ++ #bus-id = <2>; ++ #logical-bus-id = <0>; ++ bus-type = "external"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ pnor_flash: pnor_flash@18045000 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "brcm,iproc-nor"; ++ reg = nor_regs: <0x18045000 0x1000>, ++ nor_mem: <0xE8000000 0x8000000>, ++ nor_sel: <0x18000c8c 0x4>, ++ nor_strap: <0x18000a5c 0x4>; ++ status = "disabled"; ++ }; ++ ++ hwrng: hwrng@18032000 { ++ compatible = "brcm,iproc-rng"; ++ reg = <0x18032000 0x1000>; ++ rng-type = "rng200"; ++ status = "disabled"; ++ }; ++ ++ iproc_wdt: iproc_wdt@18009000 { ++ compatible = "arm,sp805", "arm,primecell"; ++ reg = iproc_wdt_base: <0x18009000 0x1000>, ++ iproc_reset_reg: <0x1800f014 0x4>; ++ wdt_boot_status_bit = <0x0>; ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ /* cmicd */ ++ iproc_cmicd: iproc_cmicd@03200000 { ++ compatible = "brcm,iproc-cmicd"; ++ reg = <0x03200000 0x100000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ }; ++ ++ pcie0: pcie@18012000 { ++ compatible = "brcm,iproc-pcie"; ++ reg = <0x18012000 0x1000>; ++ linux,pci-domain = <0>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ ; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ /*non-prefetchable mem space, pcie addr 0x0 0x20000000, ++ * cpu addr 0x20000000, size 0x0 0x20000000 ++ */ ++ ranges = <0x82000000 0 0x20000000 0x20000000 0 0x20000000>; ++ phy-addr = <0>; ++ status = "disabled"; ++ }; ++ ++ dmu_pcu: dmu_pcu@1800f000 { ++ compatible = "brcm,iproc-dmu-pcu"; ++ reg = <0x1800f000 0xc00>; ++ }; ++ ++ iproc_wrap_ctrl: iproc_wrap_ctrl@1800fc00 { ++ compatible = "brcm,iproc-wrap-ctrl"; ++ reg = <0x1800fc00 0x100>; ++ ++ }; ++ ++ iproc_idm: iproc_idm@18100000 { ++ compatible = "brcm,iproc-idm"; ++ reg = <0x18100000 0x100000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ }; ++ ++}; +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm-katana2.dtsi b/arch/arm/boot/dts/bcm-katana2.dtsi +--- a/arch/arm/boot/dts/bcm-katana2.dtsi 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm-katana2.dtsi 2017-11-09 17:52:54.687932000 +0800 +@@ -0,0 +1,431 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++#include "skeleton.dtsi" ++ ++ ++/ { ++ model = "Broadcom KT2 iProc"; ++ compatible = "brcm,katana2"; ++ interrupt-parent = <&gic>; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cpu0: cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a9"; ++ next-level-cache = <&L2>; ++ reg = <0x0>; ++ }; ++ ++ cpu1: cpu@1 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a9"; ++ next-level-cache = <&L2>; ++ enable-method = "brcm,bcm-nsp-smp"; ++ secondary-boot-reg = <0xffff042c>; ++ reg = <0x1>; ++ }; ++ }; ++ ++ mpcore { ++ compatible = "simple-bus"; ++ ranges = <0x00000000 0x19000000 0x00023000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ a9pll: arm_clk@00000 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-armpll"; ++ clocks = <&osc>; ++ reg = <0x0 0x1000>; ++ }; ++ ++ gic: interrupt-controller@21000 { ++ compatible = "arm,cortex-a9-gic"; ++ #interrupt-cells = <3>; ++ interrupt-controller; ++ reg = <0x21000 0x1000>, <0x20100 0x100>; ++ }; ++ ++ twd-timer@20600 { ++ compatible = "arm,cortex-a9-twd-timer"; ++ reg = <0x20600 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ timer@20200 { ++ compatible = "arm,cortex-a9-global-timer"; ++ reg = <0x20200 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ L2: l2-cache { ++ compatible = "arm,pl310-cache"; ++ reg = <0x22000 0x1000>; ++ cache-unified; ++ cache-level = <2>; ++ arm,filter-ranges = <0x60000000 0x80000000>; ++ }; ++ }; ++ ++ clocks { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ osc: oscillator { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <25000000>; ++ }; ++ ++ periph_clk: periph_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&a9pll>; ++ clock-div = <2>; ++ clock-mult = <1>; ++ }; ++ ++ iproc_axi_clk: axi_clk_fixed_495M { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <495000000>; ++ }; ++ ++ iproc_apb_clk: iproc_apb_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&iproc_axi_clk>; ++ clock-div = <4>; ++ clock-mult = <1>; ++ }; ++ }; ++ ++ axi { ++ compatible = "simple-bus"; ++ ranges; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ uart0: serial@18000300 { ++ compatible = "ns16550a"; ++ reg = <0x18000300 0x100>; ++ interrupts = ; ++ clock-frequency = <61875000>; ++ status = "disabled"; ++ }; ++ ++ uart1: serial@18000400 { ++ compatible = "ns16550a"; ++ reg = <0x18000400 0x100>; ++ interrupts = ; ++ clock-frequency = <61875000>; ++ status = "disabled"; ++ }; ++ ++ uart2: serial@18037000 { ++ compatible = "ns16550a"; ++ reg = <0x18037000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_cca: gpio@18000060 { ++ compatible = "brcm,iproc-gpio,cca"; ++ #gpio-cells = <2>; ++ reg = gpio: <0x18000060 0x50>, ++ intr: <0x18000000 0x50>; ++ ngpios = <8>; ++ pin-offset = <0>; ++ pin-base = <4>; ++ gpio-controller; ++ interrupt-controller; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ gmac0: ethernet@18022000 { ++ compatible = "brcm,iproc-gmac"; ++ reg = <0x18022000 0x1000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ gmac1: ethernet@18023000 { ++ compatible = "brcm,iproc-gmac"; ++ reg = <0x18023000 0x1000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ nand: nand@18026000 { ++ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; ++ reg = <0x18026000 0x600>, ++ <0x1811b408 0x10>, ++ <0x18026f00 0x20>; ++ reg-names = "nand", "iproc-idm", "iproc-ext"; ++ interrupts = ; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ brcm,nand-has-wp; ++ }; ++ ++ qspi: spi@18027000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "brcm,iproc-qspi"; ++ reg = mspi_hw:<0x18027200 0x188>, ++ bspi_hw:<0x18027000 0x050>, ++ bspi_hw_raf:<0x18027100 0x024>, ++ qspi_intr:<0x180273a0 0x01c>, ++ idm_qspi:<0x1811c408 0x004>, ++ cru_hw:<0x1803e000 0x004>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ ; ++ #chip-select = <0>; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ usbphy0: usbphy0 { ++ #phy-cells = <0>; ++ compatible = "brcm,usb-phy,kt2"; ++ reg = idm_usb2h: <0x18115000 0x1000>, ++ idm_usb2d: <0x18116000 0x1000>; ++ vbus-gpio = <&gpio_cca 1 GPIO_ACTIVE_LOW>; ++ usbdev-gpio = <&gpio_cca 0 GPIO_ACTIVE_HIGH>; ++ status = "disabled"; ++ }; ++ ++ ehci0: usb@1802a000 { ++ compatible = "generic-ehci"; ++ reg = <0x1802a000 0x1000>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ usbd: usbd@18042000 { ++ compatible = "brcm,usbd,kt2"; ++ reg = <0x18042000 0x2000>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ i2c0: i2c@0x18038000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x18038000 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ i2c1: i2c@1803b000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x1803b000 0x100>; ++ interrupts = ; ++ #bus-id = <1>; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ mdio_int: mdio_int@18032000 { ++ compatible = "brcm,iproc-ccb-mdio"; ++ reg = <0x18032000 0x1000>; ++ #bus-id = <0>; ++ bus-type = "internal"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ mdio_ext: mdio_ext@18032000 { ++ compatible = "brcm,iproc-ccb-mdio"; ++ reg = <0x18032000 0x1000>; ++ #bus-id = <0>; ++ bus-type = "external"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ hwrng: hwrng@18033000 { ++ compatible = "brcm,iproc-rng"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x18033000 0x1000>; ++ rng-type = "rng"; ++ status = "disabled"; ++ }; ++ ++ iproc_wdt: iproc_wdt@18039000 { ++ compatible = "arm,sp805", "arm,primecell"; ++ reg = iproc_wdt_base: <0x18039000 0x1000>, ++ iproc_reset_reg: <0x1803f014 0x4>; ++ wdt_boot_status_bit = <0x0>; ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ dmac0: dma@18020000 { ++ compatible = "arm,pl330", "arm,primecell"; ++ reg = pl330_base: <0x18020000 0x1000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ /*arm,primecell-periphid = <0x00041330>;*/ ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ #dma-cells = <1>; ++ #dma-channels = <8>; ++ #dma-requests = <16>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd */ ++ iproc_cmicd: iproc_cmicd@48000000 { ++ compatible = "brcm,iproc-cmicd"; ++ reg = <0x48000000 0x40000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ }; ++ ++ pcie0: pcie@18012000 { ++ compatible = "brcm,iproc-pcie", "iproc-p2"; ++ reg = <0x18012000 0x1000>; ++ linux,pci-domain = <0>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ ; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ /*non-prefetchable mem space, pcie addr 0x0 0x08000000, ++ * cpu addr 0x08000000, size 0x0 0x08000000 ++ */ ++ ranges = <0x82000000 0 0x08000000 0x08000000 0 0x08000000>; ++ phy-addr = <0>; ++ status = "disabled"; ++ }; ++ ++ pcie1: pcie@18013000 { ++ compatible = "brcm,iproc-pcie", "iproc-p2"; ++ reg = <0x18013000 0x1000>; ++ linux,pci-domain = <1>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ ; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ /*non-prefetchable mem space, pcie addr 0x0 0x40000000, ++ * cpu addr 0x40000000, size 0x0 0x08000000 ++ */ ++ ranges = <0x82000000 0 0x40000000 0x40000000 0 0x08000000>; ++ phy-addr = <1>; ++ status = "disabled"; ++ }; ++ ++ dmu_pcu: dmu_pcu@1803f000 { ++ compatible = "brcm,iproc-dmu-pcu"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x1803f000 0xc00>; ++ }; ++ ++ iproc_wrap_ctrl: iproc_wrap_ctrl@1803fc00 { ++ compatible = "brcm,iproc-wrap-ctrl"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x1803fc00 0x100>; ++ }; ++ ++ iproc_idm: iproc_idm@18100000 { ++ compatible = "brcm,iproc-idm"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x18100000 0x100000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ }; ++}; ++ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm-saber2.dtsi b/arch/arm/boot/dts/bcm-saber2.dtsi +--- a/arch/arm/boot/dts/bcm-saber2.dtsi 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm-saber2.dtsi 2017-11-09 17:52:54.689928000 +0800 +@@ -0,0 +1,356 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++#include "skeleton.dtsi" ++ ++/ { ++ model = "Broadcom SB2 iProc"; ++ compatible = "brcm,saber2"; ++ interrupt-parent = <&gic>; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a9"; ++ next-level-cache = <&L2>; ++ reg = <0x0>; ++ }; ++ }; ++ ++ core { ++ compatible = "simple-bus"; ++ ranges = <0x00000000 0x19000000 0x00023000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ a9pll: arm_clk@00000 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-armpll"; ++ clocks = <&osc>; ++ reg = <0x0 0x1000>; ++ }; ++ ++ gic: interrupt-controller@21000 { ++ compatible = "arm,cortex-a9-gic"; ++ #interrupt-cells = <3>; ++ interrupt-controller; ++ reg = <0x21000 0x1000>, <0x20100 0x100>; ++ }; ++ ++ twd-timer@20600 { ++ compatible = "arm,cortex-a9-twd-timer"; ++ reg = <0x20600 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ timer@20200 { ++ compatible = "arm,cortex-a9-global-timer"; ++ reg = <0x20200 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ L2: l2-cache { ++ compatible = "arm,pl310-cache"; ++ reg = <0x22000 0x1000>; ++ cache-unified; ++ cache-level = <2>; ++ arm,filter-ranges = <0x60000000 0x80000000>; ++ }; ++ }; ++ ++ clocks { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ osc: oscillator_25M { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <25000000>; ++ }; ++ ++ osc_1: oscillator_50M { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <50000000>; ++ }; ++ ++ periph_clk: periph_clk@19000000 { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&a9pll>; ++ clock-div = <2>; ++ clock-mult = <1>; ++ }; ++ ++ iproc_axi_clk: iproc_axi_clk@1800fc50 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-axi-clk", "axi-clk-sb2"; ++ clocks = <&osc_1>; ++ reg = <0x1800fc50 0x1c>; ++ }; ++ ++ iproc_apb_clk: iproc_apb_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&iproc_axi_clk>; ++ clock-div = <4>; ++ clock-mult = <1>; ++ }; ++ }; ++ ++ axi { ++ compatible = "simple-bus"; ++ ranges; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ uart0: serial@18020000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x18020000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ uart1: serial@18021000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x18021000 0x1000>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ qspi: spi@18047000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "brcm,iproc-qspi"; ++ reg = mspi_hw:<0x18047200 0x188>, ++ bspi_hw:<0x18047000 0x050>, ++ bspi_hw_raf:<0x18047100 0x024>, ++ qspi_intr:<0x180473a0 0x01c>, ++ idm_qspi:<0xf8106408 0x004>, ++ cru_hw:<0x1800e000 0x004>; ++ interrupts = ; ++ #chip-select = <0>; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ ++ gmac0: ethernet@18042000 { ++ compatible = "brcm,iproc-gmac"; ++ reg = <0x18042000 0x1000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ usbphy0: usbphy0 { ++ #phy-cells = <0>; ++ compatible = "brcm,usb-phy,sb2"; ++ reg = idm_usb2h: <0x18115000 0x1000>, ++ idm_usb2d: <0x18111000 0x1000>; ++ vbus-gpio = <&gpio_ccg 1 GPIO_ACTIVE_LOW>; ++ status = "disabled"; ++ }; ++ ++ ehci0: usb@18048000 { ++ compatible = "generic-ehci"; ++ reg = <0x18048000 0x800>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ ohci0: usb@18048800 { ++ compatible = "generic-ohci"; ++ reg = <0x18048800 0x800>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ usbd: usbd@1804c000 { ++ compatible = "brcm,usbd,sb2"; ++ reg = usb2d: <0x1804c000 0x2000>, ++ idm_usb: <0x18111000 0x1000>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ gpio_ccg: gpio@1800a000 { ++ compatible = "brcm,iproc-gpio,ccg"; ++ #gpio-cells = <2>; ++ reg = gpio: <0x1800a000 0x50>; ++ ngpios = <16>; ++ pin-offset = <0>; ++ pin-base = <0>; ++ gpio-controller; ++ interrupt-controller; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ nand: nand@18046000 { ++ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; ++ reg = <0x18046000 0x600>, ++ <0xf8105408 0x10>, ++ <0x18046f00 0x20>; ++ reg-names = "nand", "iproc-idm", "iproc-ext"; ++ interrupts = ; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ brcm,nand-has-wp; ++ status = "disabled"; ++ }; ++ ++ i2c0: i2c@18008000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x18008000 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ mdio_int: mdio_int@18002000 { ++ compatible = "brcm,iproc-ccg-mdio"; ++ reg = <0x18002000 0x1000>; ++ #bus-id = <0>; ++ bus-type = "internal"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ mdio_ext: mdio_ext@18002000 { ++ compatible = "brcm,iproc-ccg-mdio"; ++ reg = <0x18002000 0x1000>; ++ #bus-id = <0>; ++ bus-type = "external"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ hwrng: hwrng@18032000 { ++ compatible = "brcm,iproc-rng"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x18032000 0x1000>; ++ rng-type = "rng200"; ++ status = "disabled"; ++ }; ++ ++ iproc_wdt: iproc_wdt@18009000 { ++ compatible = "arm,sp805", "arm,primecell"; ++ reg = iproc_wdt_base: <0x18009000 0x1000>, ++ iproc_reset_reg: <0x1800f014 0x4>; ++ wdt_boot_status_bit = <0x0>; ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ /* cmicd */ ++ iproc_cmicd: iproc_cmicd@03200000 { ++ compatible = "brcm,iproc-cmicd"; ++ reg = <0x03200000 0x100000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ }; ++ ++ pcie0: pcie@18012000 { ++ compatible = "brcm,iproc-pcie", "iproc-p7"; ++ reg = <0x18012000 0x1000>; ++ linux,pci-domain = <0>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ ; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ /*non-prefetchable mem space, pcie addr 0x0 0x20000000, ++ * cpu addr 0x20000000, size 0x0 0x20000000 ++ */ ++ ranges = <0x82000000 0 0x20000000 0x20000000 0 0x20000000>; ++ phy-addr = <0>; ++ status = "disabled"; ++ }; ++ ++ dmu_pcu: dmu_pcu@1800f000 { ++ compatible = "brcm,iproc-dmu-pcu"; ++ reg = <0x1800f000 0xc00>; ++ }; ++ ++ iproc_wrap_ctrl: iproc_wrap_ctrl@1800fc00 { ++ compatible = "brcm,iproc-wrap-ctrl"; ++ reg = <0x1800fc00 0x100>; ++ }; ++ ++ iproc_idm: iproc_idm@18100000 { ++ compatible = "brcm,iproc-idm"; ++ reg = idm0: <0x18100000 0x100000>, ++ idm1: <0xf8100000 0x100000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ }; ++}; +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm-wolfhound2.dtsi b/arch/arm/boot/dts/bcm-wolfhound2.dtsi +--- a/arch/arm/boot/dts/bcm-wolfhound2.dtsi 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm-wolfhound2.dtsi 2017-11-09 17:52:54.690928000 +0800 +@@ -0,0 +1,354 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++#include "skeleton.dtsi" ++ ++ ++/ { ++ model = "Broadcom HR3 iProc"; ++ compatible = "brcm,hurricane3"; ++ interrupt-parent = <&gic>; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a9"; ++ next-level-cache = <&L2>; ++ reg = <0x0>; ++ }; ++ }; ++ ++ core { ++ compatible = "simple-bus"; ++ ranges = <0x00000000 0x19000000 0x00023000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ a9pll: arm_clk@00000 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-armpll"; ++ clocks = <&osc>; ++ reg = <0x0 0x1000>; ++ }; ++ ++ gic: interrupt-controller@21000 { ++ compatible = "arm,cortex-a9-gic"; ++ #interrupt-cells = <3>; ++ interrupt-controller; ++ reg = <0x21000 0x1000>, <0x20100 0x100>; ++ }; ++ ++ twd-timer@20600 { ++ compatible = "arm,cortex-a9-twd-timer"; ++ reg = <0x20600 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ timer@20200 { ++ compatible = "arm,cortex-a9-global-timer"; ++ reg = <0x20200 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ L2: l2-cache { ++ compatible = "arm,pl310-cache"; ++ reg = <0x22000 0x1000>; ++ cache-unified; ++ cache-level = <2>; ++ arm,filter-ranges = <0x60000000 0x80000000>; ++ }; ++ }; ++ ++ clocks { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ osc: oscillator { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <25000000>; ++ }; ++ ++ periph_clk: periph_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&a9pll>; ++ clock-div = <2>; ++ clock-mult = <1>; ++ }; ++ ++ iproc_axi_clk: iproc_axi_clk@1800fc00 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-axi-clk"; ++ clocks = <&osc>; ++ reg = <0x1800fc00 0x1c>; ++ }; ++ ++ iproc_apb_clk: iproc_apb_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&iproc_axi_clk>; ++ clock-div = <4>; ++ clock-mult = <1>; ++ }; ++ }; ++ ++ axi { ++ compatible = "simple-bus"; ++ ranges; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ uart0: serial@18020000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x18020000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ uart1: serial@18021000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x18021000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ gmac0: ethernet@18042000 { ++ compatible = "brcm,iproc-gmac"; ++ reg = <0x18042000 0x1000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ gpio_ccg: gpio@1800a000 { ++ compatible = "brcm,iproc-gpio,ccg"; ++ #gpio-cells = <2>; ++ reg = gpio: <0x1800a000 0x50>; ++ ngpios = <12>; ++ pin-offset = <4>; ++ pin-base = <4>; ++ gpio-controller; ++ interrupt-controller; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ usbphy0: usbphy0 { ++ #phy-cells = <0>; ++ compatible = "brcm,usb-phy,gh"; ++ reg = idm_usb2h: <0x18115000 0x1000>, ++ idm_usb2d: <0x18111000 0x1000>; ++ vbus-gpio = <&gpio_ccg 3 GPIO_ACTIVE_HIGH>; ++ status = "disabled"; ++ }; ++ ++ ehci0: usb@0x18048000 { ++ compatible = "generic-ehci"; ++ reg = <0x18048000 0x800>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ ohci0: usb@0x18048800 { ++ compatible = "generic-ohci"; ++ reg = <0x18048800 0x800>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ usbd: usbd@1804c000 { ++ compatible = "brcm,usbd,hr3"; ++ reg = <0x1804c000 0x2000>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ qspi: spi@18047000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "brcm,iproc-qspi"; ++ reg = mspi_hw:<0x18047200 0x188>, ++ bspi_hw:<0x18047000 0x050>, ++ bspi_hw_raf:<0x18047100 0x024>, ++ qspi_intr:<0x180473a0 0x01c>, ++ idm_qspi:<0x1811f408 0x004>, ++ cru_hw:<0x1800e000 0x004>; ++ interrupts = ; ++ #chip-select = <0>; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ i2c0: i2c@18008000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x18008000 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd cmic_common mdio */ ++ mdio_int0: mdio_int0@03210000 { ++ compatible = "brcm,iproc-cmicd-mdio"; ++ reg = <0x03210000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #bus-id = <0>; ++ #logical-bus-id = <0>; ++ bus-type = "internal"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd cmic_common mdio */ ++ mdio_int1: mdio_int1@03210000 { ++ compatible = "brcm,iproc-cmicd-mdio"; ++ reg = <0x03210000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #bus-id = <1>; ++ #logical-bus-id = <1>; ++ bus-type = "internal"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ /* CCG mdio */ ++ mdio_int2: mdio_int2@18002000 { ++ compatible = "brcm,iproc-ccg-mdio"; ++ reg = <0x18002000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #bus-id = <2>; ++ bus-type = "internal"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ hwrng: hwrng@18032000 { ++ compatible = "brcm,iproc-rng"; ++ reg = <0x18032000 0x1000>; ++ rng-type = "rng200"; ++ status = "disabled"; ++ }; ++ ++ iproc_wdt: iproc_wdt@18009000 { ++ compatible = "arm,sp805", "arm,primecell"; ++ reg = iproc_wdt_base: <0x18009000 0x1000>, ++ iproc_reset_reg: <0x1800f014 0x4>; ++ wdt_boot_status_bit = <0x0>; ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ /* cmicd */ ++ iproc_cmicd: iproc_cmicd@03200000 { ++ compatible = "brcm,iproc-cmicd"; ++ reg = <0x03200000 0x100000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ }; ++ ++ pcie0: pcie@18012000 { ++ compatible = "brcm,iproc-pcie"; ++ reg = <0x18012000 0x1000>; ++ linux,pci-domain = <0>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ ; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ /*non-prefetchable mem space, pcie addr 0x0 0x20000000, ++ * cpu addr 0x20000000, size 0x0 0x20000000 ++ */ ++ ranges = <0x82000000 0 0x20000000 0x20000000 0 0x20000000>; ++ phy-addr = <0>; ++ status = "disabled"; ++ }; ++ ++ dmu_pcu: dmu_pcu@1800f000 { ++ compatible = "brcm,iproc-dmu-pcu"; ++ reg = <0x1800f000 0xc00>; ++ }; ++ ++ iproc_wrap_ctrl: iproc_wrap_ctrl@1800fc00 { ++ compatible = "brcm,iproc-wrap-ctrl"; ++ reg = <0x1800fc00 0x100>; ++ ++ }; ++ ++ iproc_idm: iproc_idm@18100000 { ++ compatible = "brcm,iproc-idm"; ++ reg = <0x18100000 0x100000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ }; ++ ++}; +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm95341x.dts b/arch/arm/boot/dts/bcm95341x.dts +--- a/arch/arm/boot/dts/bcm95341x.dts 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm95341x.dts 2017-11-09 17:52:54.730934000 +0800 +@@ -0,0 +1,207 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/dts-v1/; ++ ++#include "bcm-greyhound.dtsi" ++ ++/ { ++ model = "Broadcom GH SVK (BCM95341x)"; ++ compatible = "brcm,bcm95341x", "brcm,greyhound"; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ ethernet0 = &gmac0; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200n8 maxcpus=1 mem=496M"; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&gmac0 { ++ status = "okay"; ++}; ++ ++&usbphy0 { ++ status = "okay"; ++}; ++ ++&ehci0 { ++ status = "okay"; ++}; ++ ++&ohci0 { ++ status = "okay"; ++}; ++ ++&usbd { ++ status = "okay"; ++}; ++ ++&gpio_ccg { ++ status = "okay"; ++}; ++ ++&pcie0 { ++ status = "okay"; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ eeprom@0x50 { ++ compatible = "atmel,24c01"; ++ reg = <0x50>; ++ pagesize = <8>; ++ }; ++}; ++ ++&nand { ++ status = "okay"; ++ nandcs@1 { ++ compatible = "brcm,nandcs"; ++ reg = <0>; ++ nand-on-flash-bbt; ++ /*nand-bus-width = <8>;*/ ++ nand-ecc-strength = <24>; ++ nand-ecc-step-size = <1024>; ++ brcm,nand-oob-sector-size = <27>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "nboot"; ++ reg = <0x0 0x200000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "nenv"; ++ reg = <0x200000 0x400000>; ++ }; ++ partition@2 { ++ label = "nsystem"; ++ reg = <0x600000 0xa00000>; ++ }; ++ partition@3 { ++ label = "nrootfs"; ++ reg = <0x1000000 0xf000000>; ++ }; ++ partition@4 { ++ label = "ncustfs"; ++ reg = <0x10000000 0x30000000>; ++ }; ++ }; ++}; ++ ++&qspi { ++ status = "okay"; ++ flash: m25p80@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "m25p80"; ++ m25p,fast-read = <1>; ++ spi-max-frequency = <62500000>; ++ reg = <0x0>; ++ partition@0 { ++ label = "boot"; ++ reg = <0x00000000 0x000c0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "env"; ++ reg = <0x000c0000 0x00040000>; ++ }; ++ partition@2 { ++ label = "system"; ++ reg = <0x00100000 0x00f00000>; ++ }; ++ partition@3 { ++ label = "rootfs"; ++ reg = <0x01000000 0x03000000>; ++ }; ++ }; ++}; ++ ++&pnor_flash { ++ status = "okay"; ++ ++ partition@0 { ++ label = "pboot"; ++ reg = <0x0 0xc0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "penv"; ++ reg = <0xc0000 0x40000>; ++ }; ++ partition@2 { ++ label = "psystem"; ++ reg = <0x100000 0xf00000>; ++ }; ++ partition@3 { ++ label = "prootfs"; ++ reg = <0x1000000 0x1000000>; ++ }; ++ partition@4 { ++ label = "pcustfs"; ++ reg = <0x2000000 0x2000000>; ++ }; ++}; ++ ++&mdio_int { ++ status = "okay"; ++}; ++ ++&mdio_ext { ++ status = "okay"; ++}; ++ ++&hwrng { ++ status = "okay"; ++}; ++ ++&iproc_wdt { ++ status = "okay"; ++}; ++ ++&iproc_cmicd { ++ status = "okay"; ++}; +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm953444.dts b/arch/arm/boot/dts/bcm953444.dts +--- a/arch/arm/boot/dts/bcm953444.dts 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm953444.dts 2017-11-09 17:52:54.731931000 +0800 +@@ -0,0 +1,128 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/dts-v1/; ++ ++#include "bcm-hurricane3.dtsi" ++ ++/ { ++ model = "Broadcom HR3 SVK (BCM953444K)"; ++ compatible = "brcm,bcm953444k", "brcm,hurricane3"; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ ethernet0 = &gmac0; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200n8 maxcpus=1 mem=496M"; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&gmac0 { ++ status = "okay"; ++}; ++ ++ ++&gpio_ccg { ++ status = "okay"; ++}; ++ ++&pcie0 { ++ status = "okay"; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ eeprom@0x50 { ++ compatible = "atmel,24c01"; ++ reg = <0x50>; ++ pagesize = <8>; ++ }; ++}; ++ ++&qspi { ++ status = "okay"; ++ flash: m25p80@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "m25p80"; ++ m25p,fast-read = <1>; ++ spi-max-frequency = <62500000>; ++ reg = <0x0>; ++ partition@0 { ++ label = "boot"; ++ reg = <0x00000000 0x000c0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "env"; ++ reg = <0x000c0000 0x00040000>; ++ }; ++ partition@2 { ++ label = "system"; ++ reg = <0x00100000 0x00f00000>; ++ }; ++ partition@3 { ++ label = "rootfs"; ++ reg = <0x01000000 0x03000000>; ++ }; ++ }; ++}; ++ ++&mdio_int { ++ status = "okay"; ++}; ++ ++&mdio_ext { ++ #bus-id = <1>; /* cmicd mdio needs #logical-bus-id in addition to #bus-id (physical) */ ++ #logical-bus-id = <1>; ++ status = "okay"; ++}; ++ ++&iproc_wdt { ++ status = "okay"; ++}; ++ ++&iproc_cmicd { ++ status = "okay"; ++}; ++ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm953547.dts b/arch/arm/boot/dts/bcm953547.dts +--- a/arch/arm/boot/dts/bcm953547.dts 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm953547.dts 2017-11-09 17:52:54.740928000 +0800 +@@ -0,0 +1,154 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/dts-v1/; ++ ++#include "bcm-wolfhound2.dtsi" ++ ++/ { ++ model = "Broadcom HR3-WH2 SVK (BCM953547K)"; ++ compatible = "brcm,bcm953547k", "brcm,hurricane3"; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ ethernet0 = &gmac0; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200n8 maxcpus=1 mem=496M"; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&gmac0 { ++ status = "okay"; ++}; ++ ++&usbphy0 { ++ status = "okay"; ++}; ++ ++&ehci0 { ++ status = "okay"; ++}; ++ ++&ohci0 { ++ status = "okay"; ++}; ++ ++&usbd { ++ status = "okay"; ++}; ++ ++&gpio_ccg { ++ status = "okay"; ++}; ++ ++&pcie0 { ++ status = "okay"; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ eeprom@0x50 { ++ compatible = "atmel,24c01"; ++ reg = <0x50>; ++ pagesize = <8>; ++ }; ++}; ++ ++&qspi { ++ status = "okay"; ++ flash: m25p80@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "m25p80"; ++ m25p,fast-read = <1>; ++ spi-max-frequency = <62500000>; ++ reg = <0x0>; ++ partition@0 { ++ label = "boot"; ++ reg = <0x00000000 0x000c0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "env"; ++ reg = <0x000c0000 0x00040000>; ++ }; ++ partition@2 { ++ label = "system"; ++ reg = <0x00100000 0x00f00000>; ++ }; ++ partition@3 { ++ label = "rootfs"; ++ reg = <0x01000000 0x03000000>; ++ }; ++ }; ++}; ++ ++&mdio_int0 { ++ status = "okay"; ++ amac_phy0: amac_phy@0 { ++ reg = <24>; ++ }; ++}; ++ ++&mdio_int1 { ++ status = "okay"; ++ amac_serdes: amac_serdes@0 { ++ reg = <20>; ++ }; ++}; ++ ++&mdio_int2 { ++ status = "okay"; ++ pcie_phy0: pcie_phy@0 { ++ reg = <2>; ++ }; ++}; ++ ++&iproc_wdt { ++ status = "okay"; ++}; ++ ++&iproc_cmicd { ++ status = "okay"; ++}; ++ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm95357x.dts b/arch/arm/boot/dts/bcm95357x.dts +--- a/arch/arm/boot/dts/bcm95357x.dts 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm95357x.dts 2017-11-09 17:52:54.744928000 +0800 +@@ -0,0 +1,224 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/dts-v1/; ++ ++#include "bcm-greyhound2.dtsi" ++ ++/ { ++ model = "Broadcom RG3 SVK (BCM95357x)"; ++ compatible = "brcm,bcm95357x", "brcm,greyhound2"; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ ethernet0 = &gmac0; ++ ethernet1 = &gmac1; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200n8 maxcpus=1 mem=496M"; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&gmac0 { ++ status = "okay"; ++}; ++ ++&gmac1 { ++ status = "okay"; ++}; ++ ++&usbphy0 { ++ status = "okay"; ++}; ++ ++&ehci0 { ++ status = "okay"; ++}; ++ ++&ohci0 { ++ status = "okay"; ++}; ++ ++&usbd { ++ status = "okay"; ++}; ++ ++&gpio_ccg { ++ status = "okay"; ++}; ++ ++&pcie0 { ++ status = "okay"; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ eeprom@0x50 { ++ compatible = "atmel,24c01"; ++ reg = <0x50>; ++ pagesize = <8>; ++ }; ++}; ++ ++&nand { ++ status = "okay"; ++ nandcs@1 { ++ compatible = "brcm,nandcs"; ++ reg = <0>; ++ nand-on-flash-bbt; ++ /*nand-bus-width = <8>;*/ ++ nand-ecc-strength = <24>; ++ nand-ecc-step-size = <1024>; ++ brcm,nand-oob-sector-size = <27>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "nboot"; ++ reg = <0x0 0x200000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "nenv"; ++ reg = <0x200000 0x400000>; ++ }; ++ partition@2 { ++ label = "nsystem"; ++ reg = <0x600000 0xa00000>; ++ }; ++ partition@3 { ++ label = "nrootfs"; ++ reg = <0x1000000 0xf000000>; ++ }; ++ partition@4 { ++ label = "ncustfs"; ++ reg = <0x10000000 0x30000000>; ++ }; ++ }; ++}; ++ ++&qspi { ++ status = "okay"; ++ flash: m25p80@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "m25p80"; ++ m25p,fast-read = <1>; ++ spi-max-frequency = <62500000>; ++ reg = <0x0>; ++ partition@0 { ++ label = "boot"; ++ reg = <0x00000000 0x000c0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "env"; ++ reg = <0x000c0000 0x00040000>; ++ }; ++ partition@2 { ++ label = "system"; ++ reg = <0x00100000 0x00f00000>; ++ }; ++ partition@3 { ++ label = "rootfs"; ++ reg = <0x01000000 0x03000000>; ++ }; ++ }; ++}; ++ ++&pnor_flash { ++ status = "okay"; ++ ++ partition@0 { ++ label = "pboot"; ++ reg = <0x0 0xc0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "penv"; ++ reg = <0xc0000 0x40000>; ++ }; ++ partition@2 { ++ label = "psystem"; ++ reg = <0x100000 0xf00000>; ++ }; ++ partition@3 { ++ label = "prootfs"; ++ reg = <0x1000000 0x1000000>; ++ }; ++ partition@4 { ++ label = "pcustfs"; ++ reg = <0x2000000 0x2000000>; ++ }; ++}; ++ ++&ccg_mdio_int { ++ status = "okay"; ++}; ++ ++&mdio_int { ++ status = "okay"; ++}; ++ ++&mdio_ext { ++ status = "okay"; ++}; ++ ++&hwrng { ++ status = "okay"; ++}; ++ ++&iproc_wdt { ++ status = "okay"; ++}; ++ ++&dmac0 { ++ status = "okay"; ++}; ++ ++&crypto { ++ status = "okay"; ++}; ++ ++&iproc_cmicd { ++ status = "okay"; ++}; +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm956150.dts b/arch/arm/boot/dts/bcm956150.dts +--- a/arch/arm/boot/dts/bcm956150.dts 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm956150.dts 2017-11-09 17:52:54.744938000 +0800 +@@ -0,0 +1,180 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/dts-v1/; ++ ++#include "bcm-hurricane2.dtsi" ++ ++/ { ++ model = "Broadcom HR2 SVK (BCM956150K)"; ++ compatible = "brcm,bcm956150k", "brcm,hurricane2"; ++ ++ aliases { ++ serial0 = &uart1; ++ serial1 = &uart0; ++ ethernet0 = &gmac0; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200n8 maxcpus=1 mem=496M"; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&gmac0 { ++ status = "okay"; ++}; ++ ++&gpio_cca { ++ status = "okay"; ++}; ++ ++&pcie0 { ++ status = "okay"; ++}; ++ ++&nand { ++ status = "okay"; ++ nandcs@1 { ++ compatible = "brcm,nandcs"; ++ reg = <0>; ++ nand-on-flash-bbt; ++ /*nand-bus-width = <8>;*/ ++ nand-ecc-strength = <24>; ++ nand-ecc-step-size = <1024>; ++ brcm,nand-oob-sector-size = <27>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "nboot"; ++ reg = <0x0 0x200000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "nenv"; ++ reg = <0x200000 0x400000>; ++ }; ++ partition@2 { ++ label = "nsystem"; ++ reg = <0x600000 0xa00000>; ++ }; ++ partition@3 { ++ label = "nrootfs"; ++ reg = <0x1000000 0xf000000>; ++ }; ++ partition@4 { ++ label = "ncustfs"; ++ reg = <0x10000000 0x70000000>; ++ }; ++ }; ++}; ++ ++&qspi { ++ status = "okay"; ++ flash: m25p80@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "m25p80"; ++ m25p,fast-read = <1>; ++ spi-max-frequency = <62500000>; ++ reg = <0x0>; ++ partition@0 { ++ label = "boot"; ++ reg = <0x00000000 0x000c0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "env"; ++ reg = <0x000c0000 0x00040000>; ++ }; ++ partition@2 { ++ label = "system"; ++ reg = <0x00100000 0x00f00000>; ++ }; ++ partition@3 { ++ label = "rootfs"; ++ reg = <0x01000000 0x01000000>; ++ }; ++ }; ++}; ++ ++&pnor_flash { ++ status = "okay"; ++ ++ partition@0 { ++ label = "pboot"; ++ reg = <0x0 0xc0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "penv"; ++ reg = <0xc0000 0x40000>; ++ }; ++ partition@2 { ++ label = "psystem"; ++ reg = <0x100000 0xf00000>; ++ }; ++ partition@3 { ++ label = "prootfs"; ++ reg = <0x1000000 0x1000000>; ++ }; ++ partition@4 { ++ label = "pcustfs"; ++ reg = <0x2000000 0x2000000>; ++ }; ++}; ++ ++&mdio_int { ++ status = "okay"; ++}; ++ ++&mdio_ext { ++ status = "okay"; ++}; ++ ++ ++&iproc_wdt { ++ status = "okay"; ++}; ++ ++&iproc_cmicd { ++ status = "okay"; ++}; ++ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm956160.dts b/arch/arm/boot/dts/bcm956160.dts +--- a/arch/arm/boot/dts/bcm956160.dts 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm956160.dts 2017-11-09 17:52:54.745938000 +0800 +@@ -0,0 +1,212 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/dts-v1/; ++ ++#include "bcm-hurricane3.dtsi" ++ ++/ { ++ model = "Broadcom HR3 SVK (BCM956160K)"; ++ compatible = "brcm,bcm956160k", "brcm,hurricane3"; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ ethernet0 = &gmac0; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200n8 maxcpus=1 mem=496M"; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&gmac0 { ++ status = "okay"; ++}; ++ ++&usbphy0 { ++ status = "okay"; ++}; ++ ++&ehci0 { ++ status = "okay"; ++}; ++ ++&ohci0 { ++ status = "okay"; ++}; ++ ++&usbd { ++ status = "okay"; ++}; ++ ++&sdio { ++ status = "okay"; ++}; ++ ++&gpio_ccg { ++ status = "okay"; ++}; ++ ++&pcie0 { ++ status = "okay"; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ eeprom@0x50 { ++ compatible = "atmel,24c01"; ++ reg = <0x50>; ++ pagesize = <8>; ++ }; ++}; ++ ++&nand { ++ status = "okay"; ++ nandcs@1 { ++ compatible = "brcm,nandcs"; ++ reg = <0>; ++ nand-on-flash-bbt; ++ /*nand-bus-width = <8>;*/ ++ nand-ecc-strength = <24>; ++ nand-ecc-step-size = <1024>; ++ brcm,nand-oob-sector-size = <27>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "nboot"; ++ reg = <0x0 0x200000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "nenv"; ++ reg = <0x200000 0x400000>; ++ }; ++ partition@2 { ++ label = "nsystem"; ++ reg = <0x600000 0xa00000>; ++ }; ++ partition@3 { ++ label = "nrootfs"; ++ reg = <0x1000000 0xf000000>; ++ }; ++ partition@4 { ++ label = "ncustfs"; ++ reg = <0x10000000 0x30000000>; ++ }; ++ }; ++}; ++ ++&qspi { ++ status = "okay"; ++ flash: m25p80@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "m25p80"; ++ m25p,fast-read = <1>; ++ spi-max-frequency = <62500000>; ++ reg = <0x0>; ++ partition@0 { ++ label = "boot"; ++ reg = <0x00000000 0x000c0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "env"; ++ reg = <0x000c0000 0x00040000>; ++ }; ++ partition@2 { ++ label = "system"; ++ reg = <0x00100000 0x00f00000>; ++ }; ++ partition@3 { ++ label = "rootfs"; ++ reg = <0x01000000 0x03000000>; ++ }; ++ }; ++}; ++ ++&pnor_flash { ++ status = "okay"; ++ ++ partition@0 { ++ label = "pboot"; ++ reg = <0x0 0xc0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "penv"; ++ reg = <0xc0000 0x40000>; ++ }; ++ partition@2 { ++ label = "psystem"; ++ reg = <0x100000 0xf00000>; ++ }; ++ partition@3 { ++ label = "prootfs"; ++ reg = <0x1000000 0x1000000>; ++ }; ++ partition@4 { ++ label = "pcustfs"; ++ reg = <0x2000000 0x2000000>; ++ }; ++}; ++ ++&mdio_int { ++ status = "okay"; ++}; ++ ++&mdio_ext { ++ status = "okay"; ++}; ++ ++&hwrng { ++ status = "okay"; ++}; ++ ++&iproc_wdt { ++ status = "okay"; ++}; ++ ++&iproc_cmicd { ++ status = "okay"; ++}; ++ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm956170.dts b/arch/arm/boot/dts/bcm956170.dts +--- a/arch/arm/boot/dts/bcm956170.dts 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm956170.dts 2017-11-09 17:52:54.746936000 +0800 +@@ -0,0 +1,239 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/dts-v1/; ++ ++#include "bcm-greyhound2.dtsi" ++ ++/ { ++ model = "Broadcom GH2 SVK (BCM956170)"; ++ compatible = "brcm,bcm956170", "brcm,greyhound2"; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ ethernet0 = &gmac0; ++ ethernet1 = &gmac1; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200n8 maxcpus=1 mem=496M"; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&gmac0 { ++ status = "okay"; ++}; ++ ++&gmac1 { ++ status = "okay"; ++}; ++ ++&usbphy0 { ++ status = "okay"; ++}; ++ ++&ehci0 { ++ status = "okay"; ++}; ++ ++&ohci0 { ++ status = "okay"; ++}; ++ ++&usbd { ++ status = "okay"; ++}; ++ ++&gpio_ccg { ++ status = "okay"; ++}; ++ ++&pcie0 { ++ status = "okay"; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ eeprom@0x50 { ++ compatible = "atmel,24c01"; ++ reg = <0x50>; ++ pagesize = <8>; ++ }; ++}; ++ ++&nand { ++ status = "okay"; ++ nandcs@1 { ++ compatible = "brcm,nandcs"; ++ reg = <0>; ++ nand-on-flash-bbt; ++ /*nand-bus-width = <8>;*/ ++ nand-ecc-strength = <24>; ++ nand-ecc-step-size = <1024>; ++ brcm,nand-oob-sector-size = <27>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "nboot"; ++ reg = <0x0 0x200000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "nenv"; ++ reg = <0x200000 0x400000>; ++ }; ++ partition@2 { ++ label = "nsystem"; ++ reg = <0x600000 0xa00000>; ++ }; ++ partition@3 { ++ label = "nrootfs"; ++ reg = <0x1000000 0xf000000>; ++ }; ++ partition@4 { ++ label = "ncustfs"; ++ reg = <0x10000000 0x30000000>; ++ }; ++ }; ++}; ++ ++&qspi { ++ status = "okay"; ++ flash: m25p80@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "m25p80"; ++ m25p,fast-read = <1>; ++ spi-max-frequency = <62500000>; ++ reg = <0x0>; ++ partition@0 { ++ label = "boot"; ++ reg = <0x00000000 0x000c0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "env"; ++ reg = <0x000c0000 0x00040000>; ++ }; ++ partition@2 { ++ label = "system"; ++ reg = <0x00100000 0x00f00000>; ++ }; ++ partition@3 { ++ label = "rootfs"; ++ reg = <0x01000000 0x03000000>; ++ }; ++ }; ++}; ++ ++&pnor_flash { ++ status = "okay"; ++ ++ partition@0 { ++ label = "pboot"; ++ reg = <0x0 0xc0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "penv"; ++ reg = <0xc0000 0x40000>; ++ }; ++ partition@2 { ++ label = "psystem"; ++ reg = <0x100000 0xf00000>; ++ }; ++ partition@3 { ++ label = "prootfs"; ++ reg = <0x1000000 0x1000000>; ++ }; ++ partition@4 { ++ label = "pcustfs"; ++ reg = <0x2000000 0x2000000>; ++ }; ++}; ++ ++&ccg_mdio_int { ++ status = "okay"; ++ pcie_phy0: pcie_phy@0 { ++ reg = <2>; ++ }; ++}; ++ ++&mdio_int { ++ status = "okay"; ++ amac_serdes0: amac_serdes@0 { ++ reg = <25>; ++ }; ++ amac_serdes1: amac_serdes@1 { ++ reg = <26>; ++ }; ++}; ++ ++&mdio_ext { ++ status = "okay"; ++ amac_phy0: amac_phy@0 { ++ reg = <16>; ++ }; ++ amac_phy1: amac_phy@1 { ++ reg = <17>; ++ }; ++}; ++ ++&hwrng { ++ status = "okay"; ++}; ++ ++&iproc_wdt { ++ status = "okay"; ++}; ++ ++&dmac0 { ++ status = "okay"; ++}; ++ ++&crypto { ++ status = "okay"; ++}; ++ ++&iproc_cmicd { ++ status = "okay"; ++}; +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm956260.dts b/arch/arm/boot/dts/bcm956260.dts +--- a/arch/arm/boot/dts/bcm956260.dts 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm956260.dts 2017-11-09 17:52:54.747931000 +0800 +@@ -0,0 +1,182 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/dts-v1/; ++ ++#include "bcm-saber2.dtsi" ++ ++/ { ++ model = "Broadcom SB2 SVK (BCM956260K)"; ++ compatible = "brcm,bcm956260k", "brcm,saber2"; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ ethernet0 = &gmac0; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200n8 maxcpus=1 mem=496M"; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&gmac0 { ++ status = "okay"; ++}; ++ ++&usbphy0 { ++ status = "okay"; ++}; ++ ++&ehci0 { ++ status = "okay"; ++}; ++ ++&ohci0 { ++ status = "okay"; ++}; ++ ++&usbd { ++ status = "okay"; ++}; ++ ++&gpio_ccg { ++ status = "okay"; ++}; ++ ++&pcie0 { ++ status = "okay"; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ eeprom@0x50 { ++ compatible = "atmel,24c64"; ++ reg = <0x50>; ++ pagesize = <32>; ++ }; ++}; ++ ++&nand { ++ status = "okay"; ++ nandcs@1 { ++ compatible = "brcm,nandcs"; ++ reg = <0>; ++ nand-on-flash-bbt; ++ /*nand-bus-width = <8>;*/ ++ nand-ecc-strength = <24>; ++ nand-ecc-step-size = <1024>; ++ brcm,nand-oob-sector-size = <27>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "nboot"; ++ reg = <0x0 0x200000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "nenv"; ++ reg = <0x200000 0x400000>; ++ }; ++ partition@2 { ++ label = "nsystem"; ++ reg = <0x600000 0xa00000>; ++ }; ++ partition@3 { ++ label = "nrootfs"; ++ reg = <0x1000000 0xf000000>; ++ }; ++ partition@4 { ++ label = "ncustfs"; ++ reg = <0x10000000 0x70000000>; ++ }; ++ }; ++}; ++ ++&qspi { ++ status = "okay"; ++ flash: m25p80@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "m25p80"; ++ m25p,fast-read = <1>; ++ spi-max-frequency = <62500000>; ++ reg = <0x0>; ++ partition@0 { ++ label = "boot"; ++ reg = <0x00000000 0x000c0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "env"; ++ reg = <0x000c0000 0x00040000>; ++ }; ++ partition@2 { ++ label = "system"; ++ reg = <0x00100000 0x00f00000>; ++ }; ++ partition@3 { ++ label = "rootfs"; ++ reg = <0x01000000 0x01000000>; ++ }; ++ }; ++}; ++ ++ ++&mdio_int { ++ status = "okay"; ++}; ++ ++&mdio_ext { ++ status = "okay"; ++}; ++ ++&hwrng { ++ status = "okay"; ++}; ++ ++&iproc_wdt { ++ status = "okay"; ++}; ++ ++&iproc_cmicd { ++ status = "okay"; ++}; +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm956340.dts b/arch/arm/boot/dts/bcm956340.dts +--- a/arch/arm/boot/dts/bcm956340.dts 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm956340.dts 2017-11-09 17:52:54.748928000 +0800 +@@ -0,0 +1,196 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/dts-v1/; ++ ++#include "bcm-helix4.dtsi" ++ ++/ { ++ model = "Broadcom HX4 SVK (BCM956340K)"; ++ compatible = "brcm,bcm956340k", "brcm,helix4"; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ ethernet0 = &gmac0; ++ ethernet1 = &gmac1; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200n8 maxcpus=2 mem=496M"; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&gmac0 { ++ status = "okay"; ++}; ++ ++&gmac1 { ++ status = "okay"; ++}; ++ ++&usbphy0 { ++ status = "okay"; ++}; ++ ++&ehci0 { ++ status = "okay"; ++}; ++ ++&usbd { ++ status = "okay"; ++}; ++ ++&gpio_cca { ++ status = "okay"; ++}; ++ ++&pcie0 { ++ status = "okay"; ++}; ++ ++&pcie1 { ++ status = "okay"; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ eeprom@0x50 { ++ compatible = "atmel,24c01"; ++ reg = <0x50>; ++ pagesize = <8>; ++ }; ++}; ++ ++&i2c1 { ++ status = "okay"; ++}; ++ ++&nand { ++ status = "okay"; ++ nandcs@1 { ++ compatible = "brcm,nandcs"; ++ reg = <0>; ++ nand-on-flash-bbt; ++ /*nand-bus-width = <8>;*/ ++ nand-ecc-strength = <24>; ++ nand-ecc-step-size = <1024>; ++ brcm,nand-oob-sector-size = <27>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "nboot"; ++ reg = <0x0 0x200000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "nenv"; ++ reg = <0x200000 0x400000>; ++ }; ++ partition@2 { ++ label = "nsystem"; ++ reg = <0x600000 0xa00000>; ++ }; ++ partition@3 { ++ label = "nrootfs"; ++ reg = <0x1000000 0xf000000>; ++ }; ++ partition@4 { ++ label = "ncustfs"; ++ reg = <0x10000000 0x70000000>; ++ }; ++ }; ++}; ++ ++&qspi { ++ status = "okay"; ++ flash: m25p80@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "m25p80"; ++ m25p,fast-read = <1>; ++ spi-max-frequency = <62500000>; ++ reg = <0x0>; ++ partition@0 { ++ label = "boot"; ++ reg = <0x00000000 0x000c0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "env"; ++ reg = <0x000c0000 0x00040000>; ++ }; ++ partition@2 { ++ label = "system"; ++ reg = <0x00100000 0x00f00000>; ++ }; ++ partition@3 { ++ label = "rootfs"; ++ reg = <0x01000000 0x01000000>; ++ }; ++ }; ++}; ++ ++ ++&mdio_int { ++ status = "okay"; ++}; ++ ++&mdio_ext { ++ status = "okay"; ++}; ++ ++&hwrng { ++ status = "okay"; ++}; ++ ++&iproc_wdt { ++ status = "okay"; ++}; ++ ++&dmac0 { ++ status = "okay"; ++}; ++ ++&iproc_cmicd { ++ status = "okay"; ++}; ++ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm956450.dts b/arch/arm/boot/dts/bcm956450.dts +--- a/arch/arm/boot/dts/bcm956450.dts 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm956450.dts 2017-11-09 17:52:54.748939000 +0800 +@@ -0,0 +1,195 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/dts-v1/; ++ ++#include "bcm-katana2.dtsi" ++ ++/ { ++ model = "Broadcom KT2 SVK (BCM956450K)"; ++ compatible = "brcm,bcm956450k", "brcm,katana2"; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ ethernet0 = &gmac0; ++ ethernet1 = &gmac1; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200n8 maxcpus=2 mem=496M"; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&gmac0 { ++ status = "okay"; ++}; ++ ++&gmac1 { ++ status = "okay"; ++}; ++ ++&usbphy0 { ++ status = "okay"; ++}; ++ ++&ehci0 { ++ status = "okay"; ++}; ++ ++&usbd { ++ status = "okay"; ++}; ++ ++&gpio_cca { ++ status = "okay"; ++}; ++ ++&pcie0 { ++ status = "okay"; ++}; ++ ++&pcie1 { ++ status = "okay"; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ eeprom@0x50 { ++ compatible = "atmel,24c01"; ++ reg = <0x50>; ++ pagesize = <8>; ++ }; ++}; ++ ++&i2c1 { ++ status = "okay"; ++}; ++ ++&nand { ++ status = "okay"; ++ nandcs@1 { ++ compatible = "brcm,nandcs"; ++ reg = <0>; ++ nand-on-flash-bbt; ++ /*nand-bus-width = <8>;*/ ++ nand-ecc-strength = <24>; ++ nand-ecc-step-size = <1024>; ++ brcm,nand-oob-sector-size = <27>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "nboot"; ++ reg = <0x0 0x200000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "nenv"; ++ reg = <0x200000 0x400000>; ++ }; ++ partition@2 { ++ label = "nsystem"; ++ reg = <0x600000 0xa00000>; ++ }; ++ partition@3 { ++ label = "nrootfs"; ++ reg = <0x1000000 0xf000000>; ++ }; ++ partition@4 { ++ label = "ncustfs"; ++ reg = <0x10000000 0x70000000>; ++ }; ++ }; ++}; ++ ++&qspi { ++ status = "okay"; ++ flash: m25p80@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "m25p80"; ++ m25p,fast-read = <1>; ++ spi-max-frequency = <62500000>; ++ reg = <0x0>; ++ partition@0 { ++ label = "boot"; ++ reg = <0x00000000 0x000c0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "env"; ++ reg = <0x000c0000 0x00040000>; ++ }; ++ partition@2 { ++ label = "system"; ++ reg = <0x00100000 0x00f00000>; ++ }; ++ partition@3 { ++ label = "rootfs"; ++ reg = <0x01000000 0x01000000>; ++ }; ++ }; ++}; ++ ++ ++&mdio_int { ++ status = "okay"; ++}; ++ ++&mdio_ext { ++ status = "okay"; ++}; ++ ++&hwrng { ++ status = "okay"; ++}; ++ ++&iproc_wdt { ++ status = "okay"; ++}; ++ ++&dmac0 { ++ status = "okay"; ++}; ++ ++&iproc_cmicd { ++ status = "okay"; ++}; +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/greyhound.its b/arch/arm/boot/dts/greyhound.its +--- a/arch/arm/boot/dts/greyhound.its 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/greyhound.its 2017-11-09 17:52:54.939941000 +0800 +@@ -0,0 +1,62 @@ ++/dts-v1/; ++ ++/ { ++ description = "Linux kernel and FDT blob"; ++ #address-cells = <1>; ++ ++ images { ++ kernel@1 { ++ description = "Broadcom iProc Linux"; ++ data = /incbin/("../zImage"); ++ type = "kernel"; ++ arch = "arm"; ++ os = "linux"; ++ compression = "none"; ++ load = <0x61008000>; ++ entry = <0x61008000>; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt@1 { ++ description = "Flattened Device Tree blob - bcm95341x.dtb"; ++ data = /incbin/("./bcm95341x.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++/* ++ fdt@2 { ++ description = "Flattened Device Tree blob - bcm95606x.dtb"; ++ data = /incbin/("./bcm95606x.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "md5"; ++ }; ++ }; ++*/ ++ }; ++ ++ configurations { ++ default = "conf@1"; ++ conf@1 { ++ description = "Boot Linux kernel with FDT blob "; ++ kernel = "kernel@1"; ++ fdt = "fdt@1"; ++ }; ++/* ++ conf@2 { ++ description = "Boot Linux kernel with FDT blob"; ++ kernel = "kernel@1"; ++ fdt = "fdt@2"; ++ }; ++*/ ++ }; ++}; ++ +\ No newline at end of file +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/greyhound2.its b/arch/arm/boot/dts/greyhound2.its +--- a/arch/arm/boot/dts/greyhound2.its 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/greyhound2.its 2017-11-09 17:52:54.945934000 +0800 +@@ -0,0 +1,62 @@ ++/dts-v1/; ++ ++/ { ++ description = "Linux kernel and FDT blob"; ++ #address-cells = <1>; ++ ++ images { ++ kernel@1 { ++ description = "Broadcom iProc Linux"; ++ data = /incbin/("../zImage"); ++ type = "kernel"; ++ arch = "arm"; ++ os = "linux"; ++ compression = "none"; ++ load = <0x61008000>; ++ entry = <0x61008000>; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt@1 { ++ description = "Flattened Device Tree blob - bcm956170.dtb"; ++ data = /incbin/("./bcm956170.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt@2 { ++ description = "Flattened Device Tree blob - bcm95357x.dtb"; ++ data = /incbin/("./bcm95357x.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ }; ++ ++ configurations { ++ default = "conf@1"; ++ conf@1 { ++ description = "Boot Linux kernel with FDT blob "; ++ kernel = "kernel@1"; ++ fdt = "fdt@1"; ++ }; ++/* ++ conf@2 { ++ description = "Boot Linux kernel with FDT blob"; ++ kernel = "kernel@1"; ++ fdt = "fdt@2"; ++ }; ++*/ ++ }; ++}; ++ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/helix4.its b/arch/arm/boot/dts/helix4.its +--- a/arch/arm/boot/dts/helix4.its 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/helix4.its 2017-11-09 17:52:54.946939000 +0800 +@@ -0,0 +1,43 @@ ++/dts-v1/; ++ ++/ { ++ description = "Linux kernel and FDT blob"; ++ #address-cells = <1>; ++ ++ images { ++ kernel@1 { ++ description = "Broadcom iProc Linux"; ++ data = /incbin/("../zImage"); ++ type = "kernel"; ++ arch = "arm"; ++ os = "linux"; ++ compression = "none"; ++ load = <0x61008000>; ++ entry = <0x61008000>; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt@1 { ++ description = "Flattened Device Tree blob - bcm956340.dtb"; ++ data = /incbin/("./bcm956340.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ }; ++ ++ configurations { ++ default = "conf@1"; ++ conf@1 { ++ description = "Boot Linux kernel with FDT blob "; ++ kernel = "kernel@1"; ++ fdt = "fdt@1"; ++ }; ++ }; ++}; ++ +\ No newline at end of file +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/hurricane2.its b/arch/arm/boot/dts/hurricane2.its +--- a/arch/arm/boot/dts/hurricane2.its 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/hurricane2.its 2017-11-09 17:52:54.966932000 +0800 +@@ -0,0 +1,43 @@ ++/dts-v1/; ++ ++/ { ++ description = "Linux kernel and FDT blob"; ++ #address-cells = <1>; ++ ++ images { ++ kernel@1 { ++ description = "Broadcom iProc Linux"; ++ data = /incbin/("../zImage"); ++ type = "kernel"; ++ arch = "arm"; ++ os = "linux"; ++ compression = "none"; ++ load = <0x81008000>; ++ entry = <0x81008000>; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt@1 { ++ description = "Flattened Device Tree blob - bcm956150.dtb"; ++ data = /incbin/("./bcm956150.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ }; ++ ++ configurations { ++ default = "conf@1"; ++ conf@1 { ++ description = "Boot Linux kernel with FDT blob "; ++ kernel = "kernel@1"; ++ fdt = "fdt@1"; ++ }; ++ }; ++}; ++ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/hurricane3.its b/arch/arm/boot/dts/hurricane3.its +--- a/arch/arm/boot/dts/hurricane3.its 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/hurricane3.its 2017-11-09 17:52:54.966943000 +0800 +@@ -0,0 +1,60 @@ ++/dts-v1/; ++ ++/ { ++ description = "Linux kernel and FDT blob"; ++ #address-cells = <1>; ++ ++ images { ++ kernel@1 { ++ description = "Broadcom iProc Linux"; ++ data = /incbin/("../zImage"); ++ type = "kernel"; ++ arch = "arm"; ++ os = "linux"; ++ compression = "none"; ++ load = <0x61008000>; ++ entry = <0x61008000>; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt@1 { ++ description = "Flattened Device Tree blob - bcm956160.dtb"; ++ data = /incbin/("./bcm956160.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt@2 { ++ description = "Flattened Device Tree blob - bcm953444.dtb"; ++ data = /incbin/("./bcm953444.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ }; ++ ++ configurations { ++ default = "conf@1"; ++ conf@1 { ++ description = "Boot Linux kernel with FDT blob 1"; ++ kernel = "kernel@1"; ++ fdt = "fdt@1"; ++ }; ++ ++ conf@2 { ++ description = "Boot Linux kernel with FDT blob 2"; ++ kernel = "kernel@1"; ++ fdt = "fdt@2"; ++ }; ++ }; ++}; ++ +\ No newline at end of file +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/katana2.its b/arch/arm/boot/dts/katana2.its +--- a/arch/arm/boot/dts/katana2.its 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/katana2.its 2017-11-09 17:52:55.281942000 +0800 +@@ -0,0 +1,43 @@ ++/dts-v1/; ++ ++/ { ++ description = "Linux kernel and FDT blob"; ++ #address-cells = <1>; ++ ++ images { ++ kernel@1 { ++ description = "Broadcom iProc Linux"; ++ data = /incbin/("../zImage"); ++ type = "kernel"; ++ arch = "arm"; ++ os = "linux"; ++ compression = "none"; ++ load = <0x61008000>; ++ entry = <0x61008000>; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt@1 { ++ description = "Flattened Device Tree blob - bcm956450.dtb"; ++ data = /incbin/("./bcm956450.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ }; ++ ++ configurations { ++ default = "conf@1"; ++ conf@1 { ++ description = "Boot Linux kernel with FDT blob "; ++ kernel = "kernel@1"; ++ fdt = "fdt@1"; ++ }; ++ }; ++}; ++ +\ No newline at end of file +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/saber2.its b/arch/arm/boot/dts/saber2.its +--- a/arch/arm/boot/dts/saber2.its 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/saber2.its 2017-11-09 17:52:55.880949000 +0800 +@@ -0,0 +1,43 @@ ++/dts-v1/; ++ ++/ { ++ description = "Linux kernel and FDT blob"; ++ #address-cells = <1>; ++ ++ images { ++ kernel@1 { ++ description = "Broadcom iProc Linux"; ++ data = /incbin/("../zImage"); ++ type = "kernel"; ++ arch = "arm"; ++ os = "linux"; ++ compression = "none"; ++ load = <0x61008000>; ++ entry = <0x61008000>; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt@1 { ++ description = "Flattened Device Tree blob - bcm956260.dtb"; ++ data = /incbin/("./bcm956260.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ }; ++ ++ configurations { ++ default = "conf@1"; ++ conf@1 { ++ description = "Boot Linux kernel with FDT blob "; ++ kernel = "kernel@1"; ++ fdt = "fdt@1"; ++ }; ++ }; ++}; ++ +\ No newline at end of file +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/wolfhound2.its b/arch/arm/boot/dts/wolfhound2.its +--- a/arch/arm/boot/dts/wolfhound2.its 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/wolfhound2.its 2017-11-09 17:52:56.333945000 +0800 +@@ -0,0 +1,60 @@ ++/dts-v1/; ++ ++/ { ++ description = "Linux kernel and FDT blob"; ++ #address-cells = <1>; ++ ++ images { ++ kernel@1 { ++ description = "Broadcom iProc Linux"; ++ data = /incbin/("../zImage"); ++ type = "kernel"; ++ arch = "arm"; ++ os = "linux"; ++ compression = "none"; ++ load = <0x61008000>; ++ entry = <0x61008000>; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt@1 { ++ description = "Flattened Device Tree blob - bcm953547.dtb"; ++ data = /incbin/("./bcm953547.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ /* fdt@2 { ++ description = "Flattened Device Tree blob - bcm953444.dtb"; ++ data = /incbin/("./bcm953444.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; */ ++ }; ++ ++ configurations { ++ default = "conf@1"; ++ conf@1 { ++ description = "Boot Linux kernel with FDT blob 1"; ++ kernel = "kernel@1"; ++ fdt = "fdt@1"; ++ }; ++ ++ /* conf@2 { ++ description = "Boot Linux kernel with FDT blob 2"; ++ kernel = "kernel@1"; ++ fdt = "fdt@2"; ++ }; */ ++ }; ++}; ++ +\ No newline at end of file +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/mach-iproc/Kconfig b/arch/arm/mach-iproc/Kconfig +--- a/arch/arm/mach-iproc/Kconfig 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/mach-iproc/Kconfig 2017-11-09 17:52:58.315964000 +0800 +@@ -0,0 +1,84 @@ ++menuconfig ARCH_XGS_IPROC ++ bool "Broadcom XGS iProc Support" if ARCH_MULTI_V7 ++ select HAVE_ARM_TWD if SMP ++ select HAVE_ARM_SCU if SMP ++ select ARM_GLOBAL_TIMER ++ select ARM_GIC ++ select ARCH_REQUIRE_GPIOLIB ++ select CACHE_L2X0 ++ select ARM_AMBA ++ select ARCH_SUPPORTS_BIG_ENDIAN ++ select CPU_ENDIAN_BE8 if CPU_BIG_ENDIAN ++ select ARM_ERRATA_754322 ++ select ARM_ERRATA_764369 if SMP ++ select ARM_ERRATA_775420 ++ help ++ This enables support for Broadcom XGS iProc based SoC chips ++ ++if ARCH_XGS_IPROC ++ ++comment "XGS iProc SoC based Machine types" ++ ++choice ++ prompt "XGS iProc SoC based Machine types" ++ default MACH_HX4 ++ ++config MACH_HX4 ++ bool "Support Broadcom Helix4 bring-up board" ++ help ++ Support for the Broadcom Helix4 bring-up board. ++ ++config MACH_HR2 ++ bool "Support Broadcom Hurricane2 bring-up board" ++ help ++ Support for the Broadcom Hurricane2 bring-up board. ++ ++config MACH_KT2 ++ bool "Support Broadcom Katana2 bring-up board" ++ help ++ Support for the Broadcom Katana2 bring-up board. ++ ++config MACH_GH ++ bool "Support Broadcom Greyhound bring-up board" ++ select MACH_IPROC_P7 ++ help ++ Support for the Broadcom Greyhound bring-up board. ++ ++config MACH_SB2 ++ bool "Support Broadcom Saber2 bring-up board" ++ select MACH_IPROC_P7 ++ help ++ Support for the Broadcom Saber2 bring-up board. ++ ++config MACH_HR3 ++ bool "Support Broadcom Hurricane3 bring-up board" ++ select MACH_IPROC_P7 ++ help ++ Support for the Broadcom Hurricane3 bring-up board. ++ ++config MACH_GH2 ++ bool "Support Broadcom Greyhound2 bring-up board" ++ select MACH_IPROC_P7 ++ help ++ Support for the Broadcom Greyhound2 bring-up board. ++endchoice ++ ++config MACH_IPROC_P7 ++ bool "Support iProc Profile 7 architecture" ++ depends on (MACH_GH || MACH_SB2 || MACH_HR3 || MACH_GH2 || MACH_WH2) ++ help ++ Support for iProc Profile 7 architecture. ++ ++config MACH_WH2 ++ bool "Support Broadcom Wolfhound2 bring-up board" ++ depends on MACH_HR3 ++ default n ++ help ++ Support for the Broadcom Wolfhound2 bring-up board. ++ ++config MACH_IPROC_EMULATION ++ bool "Support iProc emulation" ++ help ++ Support for the iProc emulation. ++ ++endif +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/mach-iproc/Makefile b/arch/arm/mach-iproc/Makefile +--- a/arch/arm/mach-iproc/Makefile 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/mach-iproc/Makefile 2017-11-09 17:52:58.316963000 +0800 +@@ -0,0 +1,3 @@ ++obj-y := board_bu.o ++obj-y += shm.o ++obj-$(CONFIG_SMP) += platsmp.o +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/mach-iproc/board_bu.c b/arch/arm/mach-iproc/board_bu.c +--- a/arch/arm/mach-iproc/board_bu.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/mach-iproc/board_bu.c 2017-11-09 17:52:58.317968000 +0800 +@@ -0,0 +1,120 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define DMU_CRU_RESET_BASE 0x200 ++ ++#if defined(CONFIG_PL330_DMA) || defined(CONFIG_XGS_IPROC_DMA330_DMA) ++/* SB2/HR3 */ ++#define DMAC_IDM_RESET_OFFSET 0xf800 ++/* HX4/KT2/HR2/GH */ ++#define DMAC_IDM_RESET_OFFSET_1 0x14800 ++#endif /* CONFIG_PL330_DMA || CONFIG_XGS_IPROC_DMA330_DMA */ ++ ++enum xgs_iproc_dev_id { ++ XGS_IPROC_HX4=0, ++ XGS_IPROC_KT2, ++ XGS_IPROC_HR2, ++ XGS_IPROC_GH, ++ XGS_IPROC_SB2, ++ XGS_IPROC_HR3, ++ XGS_IPROC_GH2, ++ XGS_IPROC_GENERIC, ++}; ++ ++const char *const xgs_iproc_dt_compat[] = { ++ "brcm,helix4", ++ "brcm,katana2", ++ "brcm,hurricane2", ++ "brcm,greyhound", ++ "brcm,saber2", ++ "brcm,hurricane3", ++ "brcm,greyhound2", ++ "brcm,xgs-iproc", ++ NULL, ++}; ++ ++#if defined(CONFIG_PL330_DMA) || defined(CONFIG_XGS_IPROC_DMA330_DMA) ++void xgs_iproc_dmac_idm_reset(void) ++{ ++ void __iomem *reset_base = NULL; ++ ++ /* Need to de-assert reset of DMAC before of_platform_populate */ ++ if (of_machine_is_compatible(xgs_iproc_dt_compat[XGS_IPROC_SB2]) || ++ of_machine_is_compatible(xgs_iproc_dt_compat[XGS_IPROC_HR3]) || ++ of_machine_is_compatible(xgs_iproc_dt_compat[XGS_IPROC_GH2])) ++ reset_base = get_iproc_idm_base(0) + DMAC_IDM_RESET_OFFSET; ++ else ++ reset_base = get_iproc_idm_base(0) + DMAC_IDM_RESET_OFFSET_1; ++ ++ if (reset_base != NULL) ++ writel(readl(reset_base) & 0xFFFFFFFE, reset_base); ++} ++#endif /* CONFIG_PL330_DMA || CONFIG_XGS_IPROC_DMA330_DMA */ ++ ++void __init xgs_iproc_init_early(void) ++{ ++ /* ++ * SDK allocates coherent buffers from atomic context. ++ * Increase size of atomic coherent pool to make sure such ++ * the allocations won't fail. ++ */ ++#ifdef CONFIG_DMA_CMA ++ /*can be overrided by "coherent_pool" in bootargs */ ++ init_dma_coherent_pool_size(SZ_1M * 16); ++#endif ++} ++ ++static void __init xgs_iproc_init(void) ++{ ++ int ret; ++ ++ ret = xgs_iproc_wrap_idm_dmu_base_reg_setup(); ++ if (ret < 0) ++ return; ++ ++#if defined(CONFIG_PL330_DMA) || defined(CONFIG_XGS_IPROC_DMA330_DMA) ++ xgs_iproc_dmac_idm_reset(); ++#endif ++ /* Populate platform devices */ ++ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); ++ ++ /* Setup IDM timeout handler */ ++ xgs_iproc_idm_timeout_handler_setup(); ++} ++ ++ ++static void xgs_iproc_restart(enum reboot_mode mode, const char *cmd) ++{ ++ void * __iomem reg_addr; ++ u32 reg; ++ ++ /* CRU_RESET register */ ++ reg_addr = (void * __iomem)(get_iproc_dmu_pcu_base() + ++ DMU_CRU_RESET_BASE); ++ /* set iproc_reset_n to 0 */ ++ reg = readl(reg_addr); ++ reg &= ~((u32) 1 << 1); ++ ++ writel(reg, reg_addr); ++ ++ /* Wait for reset */ ++ while (1) ++ cpu_do_idle(); ++} ++ ++DT_MACHINE_START(XGS_iProc_DT, "BRCM XGS iProc") ++ .init_early = xgs_iproc_init_early, ++ .init_machine = xgs_iproc_init, ++ .dt_compat = xgs_iproc_dt_compat, ++ .restart = xgs_iproc_restart, ++ .l2c_aux_val = 0, ++ .l2c_aux_mask = ~0, ++MACHINE_END +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/mach-iproc/include/plat/shm.h b/arch/arm/mach-iproc/include/plat/shm.h +--- a/arch/arm/mach-iproc/include/plat/shm.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/mach-iproc/include/plat/shm.h 2017-11-09 17:52:58.322965000 +0800 +@@ -0,0 +1,72 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++/* ++ * Header for declaring shim layer exports. ++ */ ++ ++#ifndef __SHM_DOT_H_INCLUDED__ ++#define __SHM_DOT_H_INCLUDED__ ++ ++#include ++#include ++#include ++ ++ ++#define iproc_class_create(owner, name) \ ++({ \ ++ static struct lock_class_key __key; \ ++ iproc__class_create(owner, name, &__key); \ ++}) ++ ++extern int iproc_platform_get_irq(struct platform_device *dev, unsigned int num); ++extern struct resource * ++iproc_platform_get_resource_byname(struct platform_device *dev, unsigned int type, const char *name); ++extern struct resource * ++iproc_platform_get_resource(struct platform_device *dev, unsigned int type, ++ unsigned int num); ++extern int iproc_platform_device_add_resources(struct platform_device *pdev, const struct resource *res, unsigned int num); ++ ++extern int iproc_platform_device_register(struct platform_device * pdev); ++extern void iproc_platform_device_unregister(struct platform_device * pdev); ++extern int iproc_platform_driver_register(struct platform_driver *drv); ++extern void iproc_platform_driver_unregister(struct platform_driver *drv); ++ ++extern struct platform_device *iproc_platform_device_alloc(const char *name, int id); ++ ++extern int iproc_platform_device_add(struct platform_device *pdev); ++extern void iproc_platform_device_put(struct platform_device *pdev); ++ ++extern void iproc_platform_device_put(struct platform_device *pdev); ++extern int iproc_platform_device_add(struct platform_device *pdev); ++extern void iproc_platform_device_del(struct platform_device *pdev); ++extern int iproc_sysfs_create_group(struct kobject *kobj, const struct attribute_group *grp); ++extern void iproc_sysfs_remove_group(struct kobject *kobj, const struct attribute_group *grp); ++ ++ ++extern struct class *iproc__class_create(struct module *owner, const char *name, ++ struct lock_class_key *key); ++extern void iproc_class_destroy(struct class *cls); ++extern int iproc_device_create_file(struct device *dev, ++ const struct device_attribute *attr); ++extern struct device *iproc_device_create(struct class *class, ++ struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...); ++extern void iproc_device_destroy(struct class *class, dev_t devt); ++extern void iproc_device_remove_file(struct device *dev, ++ const struct device_attribute *attr); ++extern int iproc_platform_get_irq_byname(struct platform_device *, const char *); ++ ++extern int iproc_gpio_to_irq(unsigned gpio); ++#endif /*#ifndef __SHM_DOT_H_INCLUDED__*/ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/mach-iproc/platsmp.c b/arch/arm/mach-iproc/platsmp.c +--- a/arch/arm/mach-iproc/platsmp.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/mach-iproc/platsmp.c 2017-11-09 17:52:58.323963000 +0800 +@@ -0,0 +1,210 @@ ++/* ++ * Copyright (C) 2014-2015 Broadcom Corporation ++ * Copyright 2014 Linaro Limited ++ * ++ * 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 version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++/* Size of mapped Cortex A9 SCU address space */ ++#define CORTEX_A9_SCU_SIZE 0x58 ++ ++#define SECONDARY_TIMEOUT_NS NSEC_PER_MSEC /* 1 msec (in nanoseconds) */ ++#define BOOT_ADDR_CPUID_MASK 0x3 ++ ++/* Name of device node property defining secondary boot register location */ ++#define OF_SECONDARY_BOOT "secondary-boot-reg" ++#define MPIDR_CPUID_BITMASK 0x3 ++ ++/* I/O address of register used to coordinate secondary core startup */ ++static u32 secondary_boot_addr; ++ ++/* ++ * Enable the Cortex A9 Snoop Control Unit ++ * ++ * By the time this is called we already know there are multiple ++ * cores present. We assume we're running on a Cortex A9 processor, ++ * so any trouble getting the base address register or getting the ++ * SCU base is a problem. ++ * ++ * Return 0 if successful or an error code otherwise. ++ */ ++static int __init scu_a9_enable(void) ++{ ++ unsigned long config_base; ++ void __iomem *scu_base; ++ ++ if (!scu_a9_has_base()) { ++ pr_err("no configuration base address register!\n"); ++ return -ENXIO; ++ } ++ ++ /* Config base address register value is zero for uniprocessor */ ++ config_base = scu_a9_get_base(); ++ if (!config_base) { ++ pr_err("hardware reports only one core\n"); ++ return -ENOENT; ++ } ++ ++ scu_base = ioremap((phys_addr_t)config_base, CORTEX_A9_SCU_SIZE); ++ if (!scu_base) { ++ pr_err("failed to remap config base (%lu/%u) for SCU\n", ++ config_base, CORTEX_A9_SCU_SIZE); ++ return -ENOMEM; ++ } ++ ++ scu_enable(scu_base); ++ ++ iounmap(scu_base); /* That's the last we'll need of this */ ++ ++ return 0; ++} ++ ++static int nsp_write_lut(void) ++{ ++ void __iomem *sku_rom_lut; ++ phys_addr_t secondary_startup_phy; ++ ++ if (!secondary_boot_addr) { ++ pr_warn("required secondary boot register not specified\n"); ++ return -EINVAL; ++ } ++ ++ sku_rom_lut = ioremap_nocache((phys_addr_t)secondary_boot_addr, ++ sizeof(secondary_boot_addr)); ++ if (!sku_rom_lut) { ++ pr_warn("unable to ioremap SKU-ROM LUT register\n"); ++ return -ENOMEM; ++ } ++ ++ secondary_startup_phy = virt_to_phys(secondary_startup); ++ BUG_ON(secondary_startup_phy > (phys_addr_t)U32_MAX); ++ ++ writel_relaxed(secondary_startup_phy, sku_rom_lut); ++ ++ /* Ensure the write is visible to the secondary core */ ++ smp_wmb(); ++ ++ iounmap(sku_rom_lut); ++ ++ return 0; ++} ++ ++static void __init bcm_smp_prepare_cpus(unsigned int max_cpus) ++{ ++ static cpumask_t only_cpu_0 = { CPU_BITS_CPU0 }; ++ struct device_node *cpus_node = NULL; ++ struct device_node *cpu_node = NULL; ++ int ret; ++ ++ /* ++ * This function is only called via smp_ops->smp_prepare_cpu(). ++ * That only happens if a "/cpus" device tree node exists ++ * and has an "enable-method" property that selects the SMP ++ * operations defined herein. ++ */ ++ cpus_node = of_find_node_by_path("/cpus"); ++ if (!cpus_node) ++ return; ++ ++ for_each_child_of_node(cpus_node, cpu_node) { ++ u32 cpuid; ++ ++ if (of_node_cmp(cpu_node->type, "cpu")) ++ continue; ++ ++ if (of_property_read_u32(cpu_node, "reg", &cpuid)) { ++ pr_debug("%s: missing reg property\n", ++ cpu_node->full_name); ++ ret = -ENOENT; ++ goto out; ++ } ++ ++ /* ++ * "secondary-boot-reg" property should be defined only ++ * for secondary cpu ++ */ ++ if ((cpuid & MPIDR_CPUID_BITMASK) == 1) { ++ /* ++ * Our secondary enable method requires a ++ * "secondary-boot-reg" property to specify a register ++ * address used to request the ROM code boot a secondary ++ * core. If we have any trouble getting this we fall ++ * back to uniprocessor mode. ++ */ ++ if (of_property_read_u32(cpu_node, ++ OF_SECONDARY_BOOT, ++ &secondary_boot_addr)) { ++ pr_warn("%s: no" OF_SECONDARY_BOOT "property\n", ++ cpu_node->name); ++ ret = -ENOENT; ++ goto out; ++ } ++ } ++ } ++ ++ /* ++ * Enable the SCU on Cortex A9 based SoCs. If -ENOENT is ++ * returned, the SoC reported a uniprocessor configuration. ++ * We bail on any other error. ++ */ ++ ret = scu_a9_enable(); ++out: ++ of_node_put(cpu_node); ++ of_node_put(cpus_node); ++ ++ if (ret) { ++ /* Update the CPU present map to reflect uniprocessor mode */ ++ pr_warn("disabling SMP\n"); ++ init_cpu_present(&only_cpu_0); ++ } ++} ++ ++static int nsp_boot_secondary(unsigned int cpu, struct task_struct *idle) ++{ ++ int ret; ++ ++ /* ++ * After wake up, secondary core branches to the startup ++ * address programmed at SKU ROM LUT location. ++ */ ++ ret = nsp_write_lut(); ++ if (ret) { ++ pr_err("unable to write startup addr to SKU ROM LUT\n"); ++ goto out; ++ } ++ ++ /* Send a CPU wakeup interrupt to the secondary core */ ++ arch_send_wakeup_ipi_mask(cpumask_of(cpu)); ++ ++out: ++ return ret; ++} ++ ++/* Leverage NSP SMP code for HX4/KT2 */ ++static const struct smp_operations nsp_smp_ops __initconst = { ++ .smp_prepare_cpus = bcm_smp_prepare_cpus, ++ .smp_boot_secondary = nsp_boot_secondary, ++}; ++CPU_METHOD_OF_DECLARE(bcm_smp_nsp, "brcm,bcm-nsp-smp", &nsp_smp_ops); +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/mach-iproc/shm.c b/arch/arm/mach-iproc/shm.c +--- a/arch/arm/mach-iproc/shm.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/mach-iproc/shm.c 2017-11-09 17:52:58.324964000 +0800 +@@ -0,0 +1,309 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#include "include/plat/shm.h" ++/** ++ * iproc_platform_get_irq - get an IRQ for a device ++ * wrapper function for platform_get_irq ++ * @dev: platform device ++ * @num: IRQ number index ++ */ ++int iproc_platform_get_irq(struct platform_device *dev, unsigned int num) ++{ ++ return platform_get_irq(dev, num); ++} ++EXPORT_SYMBOL(iproc_platform_get_irq); ++ ++ ++/** ++ * iproc_platform_get_resource_byname - ++ * wrapper function for platform_get_resource_byname ++ * @dev: platform device ++ * @type: resource type ++ * @name: resource name ++ */ ++struct resource * ++iproc_platform_get_resource_byname(struct platform_device *dev, ++ unsigned int type, ++ const char *name) ++{ ++ return platform_get_resource_byname(dev, type, name); ++} ++EXPORT_SYMBOL(iproc_platform_get_resource_byname); ++ ++ ++/** ++ * iproc_platform_get_resource - ++ * wrapper function for platform_get_resource ++ * @dev: platform device ++ * @type: resource type ++ * @num: resource index ++ */ ++struct resource * ++iproc_platform_get_resource(struct platform_device *dev, unsigned int type, ++ unsigned int num) ++{ ++ return platform_get_resource(dev, type, num); ++} ++EXPORT_SYMBOL(iproc_platform_get_resource); ++ ++ ++/** ++ * iproc_platform_driver_register - ++ * wrapper function for platform_driver_register ++ * @drv: platform driver structure ++ */ ++int iproc_platform_driver_register(struct platform_driver *drv) ++{ ++ return platform_driver_register(drv); ++} ++EXPORT_SYMBOL(iproc_platform_driver_register); ++ ++ ++/** ++ * iproc_platform_driver_unregister ++ * wrapper function for platform_driver_unregister ++ * @drv: platform driver structure ++ */ ++void iproc_platform_driver_unregister(struct platform_driver *drv) ++{ ++ return platform_driver_unregister(drv); ++} ++EXPORT_SYMBOL(iproc_platform_driver_unregister); ++ ++ ++/** ++ * iproc_platform_device_register - add a platform-level device ++ * wrapper function for platform_device_register ++ * @pdev: platform device we're adding ++ * ++ */ ++int iproc_platform_device_register(struct platform_device * pdev) ++{ ++ return platform_device_register(pdev); ++} ++EXPORT_SYMBOL(iproc_platform_device_register); ++ ++ ++/** ++ * iproc_platform_device_unregister - ++ * wrapper function for platform_device_unregister ++ * @pdev: platform device we're unregistering ++ */ ++void iproc_platform_device_unregister(struct platform_device * pdev) ++{ ++ return platform_device_unregister(pdev); ++} ++EXPORT_SYMBOL(iproc_platform_device_unregister); ++ ++ ++/** ++ * iproc_platform_device_alloc - ++ * wrapper function for platform_device_alloc ++ * @name: base name of the device we're adding ++ * @id: instance id ++ */ ++struct platform_device *iproc_platform_device_alloc(const char *name, int id) ++{ ++ return platform_device_alloc(name, id); ++} ++EXPORT_SYMBOL(iproc_platform_device_alloc); ++ ++/** ++ * iproc_platform_device_add - ++ * wrapper function for platform_device_add ++ * @pdev: platform device we're adding ++ */ ++int iproc_platform_device_add(struct platform_device *pdev) ++{ ++ return platform_device_add(pdev); ++} ++EXPORT_SYMBOL(iproc_platform_device_add); ++ ++/** ++ * iproc_platform_device_del - ++ * wrapper function for platform_device_del ++ * @pdev: platform device we're removing ++ */ ++void iproc_platform_device_del(struct platform_device *pdev) ++{ ++ platform_device_del(pdev); ++} ++EXPORT_SYMBOL(iproc_platform_device_del); ++ ++ ++/** ++ * iproc_platform_device_put - ++ * wrapper function for platform_device_put ++ * @pdev: platform device to free ++ */ ++void iproc_platform_device_put(struct platform_device *pdev) ++{ ++ platform_device_put(pdev); ++} ++EXPORT_SYMBOL(iproc_platform_device_put); ++ ++ ++/** ++ * iproc_platform_device_add_resources - ++ * wrapper function for platform_device_add_resources ++ * @pdev: platform device allocated by platform_device_alloc to add resources to ++ * @res: set of resources that needs to be allocated for the device ++ * @num: number of resources ++ */ ++int iproc_platform_device_add_resources(struct platform_device *pdev, ++ const struct resource *res, unsigned int num) ++{ ++ return platform_device_add_resources(pdev, res, num); ++} ++EXPORT_SYMBOL(iproc_platform_device_add_resources); ++ ++ ++/** ++ * iproc_platform_device_put - ++ * wrapper function for sysfs_create_group ++ * @kobj: The kobject to create the group on ++ * @grp: The attribute group to create ++ */ ++int iproc_sysfs_create_group(struct kobject *kobj, const struct attribute_group *grp) ++{ ++ return sysfs_create_group(kobj, grp); ++} ++EXPORT_SYMBOL(iproc_sysfs_create_group); ++ ++ ++/** ++ * iproc_sysfs_remove_group - ++ * wrapper function for sysfs_remove_group ++ * @kobj: The kobject which the group is on ++ * @grp: The attribute group to remove ++ */ ++void iproc_sysfs_remove_group(struct kobject * kobj, const struct attribute_group * grp) ++{ ++ sysfs_remove_group(kobj, grp); ++} ++EXPORT_SYMBOL(iproc_sysfs_remove_group); ++ ++/** ++ * iproc__class_create - ++ * wrapper function for __class_create ++ * @ower: pointer to the module that is to "own" this struct class ++ * @name: pointer to a string for the name of this class. ++ * @key: the lock_class_key for this class; used by mutex lock debugging ++ */ ++struct class *iproc__class_create(struct module *owner, const char *name, ++ struct lock_class_key *key) ++{ ++ return __class_create(owner, name, key); ++} ++EXPORT_SYMBOL(iproc__class_create); ++ ++/** ++ * iproc_class_destroy - ++ * wrapper function for class_destroy ++ * @cls: pointer to the struct class that is to be destroyed ++ */ ++void iproc_class_destroy(struct class *cls) ++{ ++ class_destroy(cls); ++} ++EXPORT_SYMBOL(iproc_class_destroy); ++ ++/** ++ * iproc_device_create_file - ++ * wrapper function for device_create_file ++ * @dev: device. ++ * @attr: device attribute descriptor. ++ */ ++int iproc_device_create_file(struct device *dev, ++ const struct device_attribute *attr) ++{ ++ return device_create_file(dev, attr); ++} ++EXPORT_SYMBOL(iproc_device_create_file); ++ ++/** ++ * iproc_device_create - ++ * wrapper function for device_create ++ * ++ * @class: pointer to the struct class that this device should be ++ * registered to ++ * @parent: pointer to the parent struct device of this new device, if any ++ * @devt: the dev_t for the char device to be added ++ * @drvdata: the data to be added to the device for callbacks ++ * @fmt: string for the device's name ++ */ ++struct device *iproc_device_create(struct class *class, ++ struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...) ++{ ++ va_list args; ++ struct device *r; ++ ++ va_start(args, fmt); ++ r = device_create_vargs(class, parent, devt, drvdata, fmt, args); ++ va_end(args); ++ ++ return r; ++} ++EXPORT_SYMBOL(iproc_device_create); ++ ++/** ++ * iproc_device_destroy - ++ * wrapper function for device_destroy ++ * @class: pointer to the struct class that this device was registered with ++ * @devt: the dev_t of the device that was previously registered ++ */ ++void iproc_device_destroy(struct class *class, dev_t devt) ++{ ++ return device_destroy(class, devt); ++} ++EXPORT_SYMBOL(iproc_device_destroy); ++ ++/** ++ * proc_device_remove_file - ++ * wrapper function for device_remove_file ++ * @dev: device. ++ * @attr: device attribute descriptor. ++ */ ++void iproc_device_remove_file(struct device *dev, ++ const struct device_attribute *attr) ++{ ++ return device_remove_file(dev, attr); ++} ++EXPORT_SYMBOL(iproc_device_remove_file); ++ ++/** ++ * iproc_platform_get_irq_byname - ++ * wrapper function for platform_get_irq_byname ++ * @dev: platform device ++ * @name: IRQ name ++ */ ++int iproc_platform_get_irq_byname(struct platform_device *dev, const char *n) ++{ ++ return platform_get_irq_byname(dev,n); ++} ++EXPORT_SYMBOL(iproc_platform_get_irq_byname); ++ ++/** ++ * iproc_gpio_to_irq - ++ * wrapper function for gpio_to_irq ++ * @gpio: gpio whose IRQ will be returned (already requested) ++ */ ++int iproc_gpio_to_irq(unsigned gpio) ++{ ++ return gpio_to_irq(gpio); ++} ++EXPORT_SYMBOL(iproc_gpio_to_irq); +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig +--- a/drivers/char/hw_random/Kconfig 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/char/hw_random/Kconfig 2017-11-09 17:53:25.197163000 +0800 +@@ -114,6 +114,18 @@ config HW_RANDOM_IPROC_RNG200 + + If unsure, say Y. + ++config HW_RANDOM_XGS_IPROC_RNG ++ tristate "Broadcom iProc RNG support" ++ depends on (ARCH_XGS_IPROC && HW_RANDOM) ++ ---help--- ++ This driver provides kernel-side support for the RNG ++ hardware found on the Broadcom iProc SoCs. ++ ++ To compile this driver as a module, choose M here: the ++ module will be called iproc-rng ++ ++ If unsure, say Y. ++ + config HW_RANDOM_GEODE + tristate "AMD Geode HW Random Number Generator support" + depends on X86_32 && PCI +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile +--- a/drivers/char/hw_random/Makefile 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/char/hw_random/Makefile 2017-11-09 17:53:25.198159000 +0800 +@@ -29,6 +29,7 @@ obj-$(CONFIG_HW_RANDOM_EXYNOS) += exynos + obj-$(CONFIG_HW_RANDOM_TPM) += tpm-rng.o + obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o + obj-$(CONFIG_HW_RANDOM_IPROC_RNG200) += iproc-rng200.o ++obj-$(CONFIG_HW_RANDOM_XGS_IPROC_RNG) += xgs-iproc-rng200.o + obj-$(CONFIG_HW_RANDOM_MSM) += msm-rng.o + obj-$(CONFIG_HW_RANDOM_ST) += st-rng.o + obj-$(CONFIG_HW_RANDOM_XGENE) += xgene-rng.o +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/char/hw_random/xgs-iproc-rng200.c b/drivers/char/hw_random/xgs-iproc-rng200.c +--- a/drivers/char/hw_random/xgs-iproc-rng200.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/char/hw_random/xgs-iproc-rng200.c 2017-11-09 17:53:25.250157000 +0800 +@@ -0,0 +1,442 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ */ ++ ++/* ++ * DESCRIPTION: The Broadcom iProc RNG200 Driver ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Registers for RNG */ ++#define RNG_CTRL_OFFSET 0x00000000 ++#define RNG_CTRL_RESERVED_MASK 0xF00000CC ++#define RNG_CTRL_COMBLK2_OSC_DIS_SHIFT 22 ++#define RNG_CTRL_COMBLK2_OSC_DIS_MASK 0x0FC00000 ++#define RNG_CTRL_COMBLK1_OSC_DIS_SHIFT 16 ++#define RNG_CTRL_COMBLK1_OSC_DIS_MASK 0x003F0000 ++#define RNG_CTRL_JCLK_BYP_DIV_CNT_SHIFT 8 ++#define RNG_CTRL_JCLK_BYP_DIV_CNT_MASK 0x0000FF00 ++#define RNG_CTRL_JCLK_BYP_SRC_SHIFT 5 ++#define RNG_CTRL_JCLK_BYP_SRC_MASK 0x00000020 ++#define RNG_CTRL_JCLK_BYP_SEL_SHIFT 4 ++#define RNG_CTRL_JCLK_BYP_SEL_MASK 0x00000010 ++#define RNG_CTRL_RBG2X_SHIFT 1 ++#define RNG_CTRL_RBG2X_MASK 0x00000002 ++#define RNG_CTRL_RBGEN_SHIFT 0 ++#define RNG_CTRL_RBGEN_MASK 0x00000001 ++ ++#define RNG_STATUS_OFFSET 0x00000004 ++#define RNG_STATUS_RESERVED_MASK 0x00F00000 ++#define RNG_STATUS_RND_VAL_SHIFT 24 ++#define RNG_STATUS_RND_VAL_MASK 0xFF000000 ++#define RNG_STATUS_WARM_CNT_SHIFT 0 ++#define RNG_STATUS_WARM_CNT_MASK 0x000FFFFF ++ ++#define RNG_DATA_OFFSET 0x00000008 ++#define RNG_DATA_RESERVED_MASK 0x00000000 ++#define RNG_DATA_RNG_NUM_SHIFT 0 ++#define RNG_DATA_RNG_NUM_MASK 0xFFFFFFFF ++ ++#define RNG_FF_THRES_OFFSET 0x0000000C ++#define RNG_FF_THRES_RESERVED_MASK 0xFFFFFFE0 ++#define RNG_FF_THRES_RNG_FF_THRESH_SHIFT 0 ++#define RNG_FF_THRES_RNG_FF_THRESH_MASK 0x0000001F ++ ++#define RNG_INT_MASK_OFFSET 0x00000010 ++#define RNG_INT_MASK_RESERVED_MASK 0xFFFFFFFE ++#define RNG_INT_MASK_OFF_SHIFT 0 ++#define RNG_INT_MASK_OFF_MASK 0x00000001 ++ ++/* Registers for RNG200*/ ++#define RNG200_CTRL_OFFSET 0x00 ++#define RNG200_CTRL_RBGEN_MASK 0x00001FFF ++#define RNG200_CTRL_RBGEN_ENABLE 0x00000001 ++#define RNG200_CTRL_RBGEN_DISABLE 0x00000000 ++ ++#define RNG200_SOFT_RESET_OFFSET 0x04 ++#define RNG200_SOFT_RESET_MASK 0x00000001 ++#define RNG200_SOFT_RESET_ACTIVE 0x00000001 ++#define RNG200_SOFT_RESET_CLEAR 0x00000000 ++ ++#define RBG_SOFT_RESET_OFFSET 0x08 ++#define RBG_RNG_SOFT_RESET_MASK 0x00000001 ++#define RBG_RNG_SOFT_RESET_ACTIVE 0x00000001 ++#define RBG_RNG_SOFT_RESET_CLEAR 0x00000000 ++ ++#define RNG200_INT_STATUS_OFFSET 0x18 ++#define RNG200_INT_STATUS_MASTER_FAIL_LOCKOUT_IRQ_MASK 0x80000000 ++#define RNG200_INT_STATUS_STARTUP_TRANSITIONS_MET_IRQ_MASK 0x00020000 ++#define RNG200_INT_STATUS_NIST_FAIL_IRQ_MASK 0x00000020 ++#define RNG200_INT_STATUS_TOTAL_BITS_COUNT_IRQ_MASK 0x00000001 ++ ++#define RNG200_FIFO_DATA_OFFSET 0x20 ++#define RNG200_FIFO_COUNT_OFFSET 0x24 ++#define RNG200_FIFO_COUNT_MASK 0x000000FF ++ ++static int rng_read(struct hwrng *rng, void *buf, size_t max, ++ bool wait) ++{ ++ u32 num_words = 0; ++ u32 num_remaining = max; ++ ++ #define MAX_IDLE_TIME (1 * HZ) ++ unsigned long idle_endtime = jiffies + MAX_IDLE_TIME; ++ ++ /* Retrieve HW RNG registers base address. */ ++ void __iomem *base_addr = (void __iomem *)rng->priv; ++ ++ while ((num_remaining > 0) && time_before(jiffies, idle_endtime)) { ++ /* Are there any random numbers available? */ ++ num_words = (ioread32(base_addr + RNG_STATUS_OFFSET) & ++ RNG_STATUS_RND_VAL_MASK) >> RNG_STATUS_RND_VAL_SHIFT; ++ if (num_words > 0) { ++ if (num_remaining >= sizeof(u32)) { ++ /* Buffer has room to store entire word */ ++ *(u32 *)buf = ioread32(base_addr + ++ RNG_DATA_OFFSET); ++ buf += sizeof(u32); ++ num_remaining -= sizeof(u32); ++ } else { ++ /* Buffer can only store partial word */ ++ u32 rnd_number = ioread32(base_addr + ++ RNG_DATA_OFFSET); ++ memcpy(buf, &rnd_number, num_remaining); ++ buf += num_remaining; ++ num_remaining = 0; ++ } ++ ++ /* Reset the IDLE timeout */ ++ idle_endtime = jiffies + MAX_IDLE_TIME; ++ } else if (!wait) { ++ /* Cannot wait, return immediately */ ++ break; ++ } else { ++ /* Can wait, give others chance to run */ ++ cpu_relax(); ++ } ++ } ++ ++ return max - num_remaining; ++} ++ ++static struct hwrng rng_ops = { ++ .name = "iproc-rng", ++ .read = rng_read, ++}; ++ ++static int rng_probe(struct platform_device *pdev) ++{ ++ int error; ++ u32 val; ++ struct device *dev = &pdev->dev; ++ void __iomem *base_addr; ++ struct device_node *node; ++ ++ pr_info("Broadcom IPROC RNG Driver\n"); ++ /* We only accept one device, and it must have an id of -1 */ ++ if (pdev->id != -1) ++ return -ENODEV; ++ ++ node = pdev->dev.of_node; ++ base_addr = of_iomap(node, 0); ++ if (!base_addr) { ++ dev_err(&pdev->dev, "can't iomap base_addr for rng\n"); ++ return -EIO; ++ } ++ rng_ops.priv = (unsigned long)base_addr; ++ ++ /* Start RNG block */ ++ val = ioread32(base_addr + RNG_CTRL_OFFSET); ++ val |= RNG_CTRL_RBGEN_MASK; ++ iowrite32(val, base_addr + RNG_CTRL_OFFSET); ++ ++ /* Enable RNG RBG2X */ ++ val = ioread32(base_addr + RNG_CTRL_OFFSET); ++ val |= RNG_CTRL_RBG2X_MASK; ++ iowrite32(val, base_addr + RNG_CTRL_OFFSET); ++ ++ /* Disable RNG INTERRUPT */ ++ val = ioread32(base_addr + RNG_INT_MASK_OFFSET); ++ val |= RNG_INT_MASK_OFF_MASK; ++ iowrite32(val, base_addr + RNG_INT_MASK_OFFSET); ++ ++ /* set warmup cycle 0xfff */ ++ iowrite32(RNG_STATUS_WARM_CNT_MASK - ++ (0xfff & RNG_STATUS_WARM_CNT_MASK), ++ base_addr + RNG_STATUS_OFFSET); ++ while ((ioread32(base_addr + RNG_STATUS_OFFSET) & ++ RNG_STATUS_WARM_CNT_MASK) != RNG_STATUS_WARM_CNT_MASK) ++ cpu_relax(); ++ ++ /* register to the Linux RNG framework */ ++ error = hwrng_register(&rng_ops); ++ if (error) { ++ dev_err(dev, "hwrng registration failed\n"); ++ iounmap(base_addr); ++ return error; ++ } ++ dev_dbg(dev, "hwrng registered\n"); ++ ++ return 0; ++} ++ ++static int rng_remove(struct platform_device *pdev) ++{ ++ u32 val; ++ void __iomem *base_addr = (void __iomem *)rng_ops.priv; ++ /* Unregister driver */ ++ hwrng_unregister(&rng_ops); ++ ++ if (base_addr) { ++ /* Disable RNG hardware */ ++ val = ioread32(base_addr + RNG_CTRL_OFFSET); ++ val &= ~RNG_CTRL_RBGEN_MASK; ++ iowrite32(val, base_addr + RNG_CTRL_OFFSET); ++ ++ val = ioread32(base_addr + RNG_CTRL_OFFSET); ++ val &= ~RNG_CTRL_RBG2X_MASK; ++ iowrite32(val, base_addr + RNG_CTRL_OFFSET); ++ ++ iounmap(base_addr); ++ } ++ ++ return 0; ++} ++ ++static void iproc_rng200_restart(void __iomem *rng_base) ++{ ++ u32 val; ++ ++ /* Disable RBG */ ++ val = ioread32(rng_base + RNG200_CTRL_OFFSET); ++ val &= ~RNG200_CTRL_RBGEN_MASK; ++ val |= RNG200_CTRL_RBGEN_DISABLE; ++ iowrite32(val, rng_base + RNG200_CTRL_OFFSET); ++ ++ /* Clear all interrupt status */ ++ iowrite32(0xFFFFFFFFUL, rng_base + RNG200_INT_STATUS_OFFSET); ++ ++ /* Reset RNG and RBG */ ++ val = ioread32(rng_base + RBG_SOFT_RESET_OFFSET); ++ val &= ~RBG_RNG_SOFT_RESET_MASK; ++ val |= RBG_RNG_SOFT_RESET_ACTIVE; ++ iowrite32(val, rng_base + RBG_SOFT_RESET_OFFSET); ++ ++ val = ioread32(rng_base + RNG200_SOFT_RESET_OFFSET); ++ val &= ~RNG200_SOFT_RESET_MASK; ++ val |= RNG200_SOFT_RESET_ACTIVE; ++ iowrite32(val, rng_base + RNG200_SOFT_RESET_OFFSET); ++ ++ val = ioread32(rng_base + RNG200_SOFT_RESET_OFFSET); ++ val &= ~RNG200_SOFT_RESET_MASK; ++ val |= RNG200_SOFT_RESET_CLEAR; ++ iowrite32(val, rng_base + RNG200_SOFT_RESET_OFFSET); ++ ++ val = ioread32(rng_base + RBG_SOFT_RESET_OFFSET); ++ val &= ~RBG_RNG_SOFT_RESET_MASK; ++ val |= RBG_RNG_SOFT_RESET_CLEAR; ++ iowrite32(val, rng_base + RBG_SOFT_RESET_OFFSET); ++ ++ /* Enable RBG */ ++ val = ioread32(rng_base + RNG200_CTRL_OFFSET); ++ val &= ~RNG200_CTRL_RBGEN_MASK; ++ val |= RNG200_CTRL_RBGEN_ENABLE; ++ iowrite32(val, rng_base + RNG200_CTRL_OFFSET); ++} ++ ++static int iproc_rng200_read(struct hwrng *rng, void *buf, size_t max, ++ bool wait) ++{ ++ u32 status; ++ u32 rng_fifo; ++ u32 num_remaining = max; ++ ++ #define MAX_RESETS_PER_READ 1 ++ u32 num_resets = 0; ++ ++ #define MAX_IDLE_TIME (1 * HZ) ++ unsigned long idle_endtime = jiffies + MAX_IDLE_TIME; ++ ++ /* Retrieve HW RNG registers base address. */ ++ void __iomem *rng_base = (void __iomem *)rng->priv; ++ ++ while ((num_remaining > 0) && time_before(jiffies, idle_endtime)) { ++ ++ /* Is RNG sane? If not, reset it. */ ++ status = ioread32(rng_base + RNG200_INT_STATUS_OFFSET); ++ if ((status & (RNG200_INT_STATUS_MASTER_FAIL_LOCKOUT_IRQ_MASK | ++ RNG200_INT_STATUS_NIST_FAIL_IRQ_MASK)) != 0) { ++ ++ if (num_resets >= MAX_RESETS_PER_READ) ++ return max - num_remaining; ++ ++ iproc_rng200_restart(rng_base); ++ num_resets++; ++ } ++ ++ /* Are there any random numbers available? */ ++ rng_fifo = ioread32(rng_base + RNG200_FIFO_COUNT_OFFSET); ++ if ((rng_fifo & RNG200_FIFO_COUNT_MASK) > 0) { ++ ++ if (num_remaining >= sizeof(u32)) { ++ /* Buffer has room to store entire word */ ++ *(u32 *)buf = ioread32(rng_base + ++ RNG200_FIFO_DATA_OFFSET); ++ buf += sizeof(u32); ++ num_remaining -= sizeof(u32); ++ } else { ++ /* Buffer can only store partial word */ ++ u32 rnd_number = ioread32(rng_base + ++ RNG200_FIFO_DATA_OFFSET); ++ memcpy(buf, &rnd_number, num_remaining); ++ buf += num_remaining; ++ num_remaining = 0; ++ } ++ ++ /* Reset the IDLE timeout */ ++ idle_endtime = jiffies + MAX_IDLE_TIME; ++ } else { ++ if (!wait) ++ /* Cannot wait, return immediately */ ++ break; ++ ++ /* Can wait, give others chance to run */ ++ cpu_relax(); ++ } ++ } ++ ++ return max - num_remaining; ++} ++ ++static struct hwrng iproc_rng200_ops = { ++ .name = "iproc-rng200", ++ .read = iproc_rng200_read, ++}; ++ ++static int iproc_rng200_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ void __iomem *rng_base; ++ struct resource *res; ++ u32 val; ++ int err; ++ ++ pr_info("Broadcom IPROC RNG200 Driver\n"); ++ /* Map peripheral */ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!res) { ++ dev_err(dev, "failed to get rng resources"); ++ return -ENODEV; ++ } ++ ++ rng_base = devm_ioremap_resource(dev, res); ++ //rng_base = ioremap(res->start, res->end - res->start); ++ if (!rng_base) { ++ dev_err(dev, "failed to remap rng regs"); ++ return -ENODEV; ++ } ++ ++ iproc_rng200_ops.priv = (unsigned long)rng_base; ++ ++ /* Setup RNG. */ ++ val = ioread32(rng_base + RNG200_CTRL_OFFSET); ++ val &= ~RNG200_CTRL_RBGEN_MASK; ++ val |= RNG200_CTRL_RBGEN_ENABLE; ++ iowrite32(val, rng_base + RNG200_CTRL_OFFSET); ++ ++ /* Register driver */ ++ err = hwrng_register(&iproc_rng200_ops); ++ if (err) { ++ dev_err(dev, "hwrng registration failed\n"); ++ return err; ++ } ++ dev_dbg(dev, "hwrng registered\n"); ++ ++ return 0; ++} ++ ++static int iproc_rng200_remove(struct platform_device *pdev) ++{ ++ u32 val; ++ void __iomem *rng_base = (void __iomem *)iproc_rng200_ops.priv; ++ ++ /* Unregister driver */ ++ hwrng_unregister(&iproc_rng200_ops); ++ if (rng_base) { ++ /* Disable RNG hardware */ ++ val = ioread32(rng_base + RNG200_CTRL_OFFSET); ++ val &= ~RNG200_CTRL_RBGEN_MASK; ++ val |= RNG200_CTRL_RBGEN_DISABLE; ++ iowrite32(val, rng_base + RNG200_CTRL_OFFSET); ++ } ++ return 0; ++} ++static int rng_probe_gen(struct platform_device *pdev) ++{ ++ int ret = -ENODEV; ++ struct device_node *node; ++ const char *rng_name; ++ node = pdev->dev.of_node; ++ rng_name = node->name; ++ ++ if (!of_device_is_available(node)) ++ return -ENODEV; ++ ++ of_property_read_string(node, "rng-type", &rng_name); ++ if (strcmp(rng_name, "rng200") == 0) ++ ret = iproc_rng200_probe(pdev); ++ else if (strcmp(rng_name, "rng") == 0) ++ ret = rng_probe(pdev); ++ ++ return ret; ++} ++ ++static int rng_remove_gen(struct platform_device *pdev) ++{ ++ int ret = -ENODEV; ++ struct device_node *node; ++ const char *rng_name; ++ node = pdev->dev.of_node; ++ rng_name = node->name; ++ ++ if (!of_device_is_available(node)) ++ return -ENODEV; ++ ++ of_property_read_string(node, "rng-type", &rng_name); ++ if (strcmp(rng_name, "rng200") == 0) ++ ret = iproc_rng200_remove(pdev); ++ else if (strcmp(rng_name, "rng") == 0) ++ ret = rng_remove(pdev); ++ ++ return ret; ++} ++ ++static const struct of_device_id bcm_iproc_dt_ids[] = { ++ { .compatible = "brcm,iproc-rng"}, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, bcm_iproc_dt_ids); ++ ++static struct platform_driver iproc_rng_driver = { ++ .driver = { ++ .name = "iproc-rng", ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(bcm_iproc_dt_ids), ++ }, ++ .probe = rng_probe_gen, ++ .remove = rng_remove_gen, ++}; ++module_platform_driver(iproc_rng_driver); ++ ++MODULE_AUTHOR("Broadcom"); ++MODULE_DESCRIPTION("iProc RNG/RNG200 Random Number Generator driver"); ++MODULE_LICENSE("GPL v2"); +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/clk/bcm/Kconfig b/drivers/clk/bcm/Kconfig +--- a/drivers/clk/bcm/Kconfig 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/clk/bcm/Kconfig 2017-11-09 17:53:25.478158000 +0800 +@@ -14,3 +14,15 @@ config COMMON_CLK_IPROC + help + Enable common clock framework support for Broadcom SoCs + based on the iProc architecture ++ ++config CLK_XGS_IPROC ++ bool "BRCM XGS iProc clock support" ++ depends on COMMON_CLK && ARCH_XGS_IPROC ++ select COMMON_CLK_IPROC ++ default ARCH_XGS_IPROC ++ help ++ Enable XGS iProc clock ++ ++ ++ ++ +\ No newline at end of file +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile +--- a/drivers/clk/bcm/Makefile 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/clk/bcm/Makefile 2017-11-09 17:53:25.479153000 +0800 +@@ -8,3 +8,4 @@ obj-$(CONFIG_COMMON_CLK_IPROC) += clk-ns + obj-$(CONFIG_ARCH_BCM_CYGNUS) += clk-cygnus.o + obj-$(CONFIG_ARCH_BCM_NSP) += clk-nsp.o + obj-$(CONFIG_ARCH_BCM_5301X) += clk-nsp.o ++obj-$(CONFIG_CLK_XGS_IPROC) += clk-xgs-iproc.o +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/clk/bcm/clk-iproc-armpll.c b/drivers/clk/bcm/clk-iproc-armpll.c +--- a/drivers/clk/bcm/clk-iproc-armpll.c 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/clk/bcm/clk-iproc-armpll.c 2017-11-09 17:53:25.494157000 +0800 +@@ -224,8 +224,10 @@ static unsigned long iproc_arm_pll_recal + pll->rate = 0; + return 0; + } ++ ++ /* To avoid pll->rate overflow, do divide before multiply */ ++ parent_rate = (parent_rate / pdiv) / mdiv; + pll->rate = (ndiv * parent_rate) >> 20; +- pll->rate = (pll->rate / pdiv) / mdiv; + + pr_debug("%s: ARM PLL rate: %lu. parent rate: %lu\n", __func__, + pll->rate, parent_rate); +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/clk/bcm/clk-xgs-iproc.c b/drivers/clk/bcm/clk-xgs-iproc.c +--- a/drivers/clk/bcm/clk-xgs-iproc.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/clk/bcm/clk-xgs-iproc.c 2017-11-09 17:53:25.512166000 +0800 +@@ -0,0 +1,170 @@ ++/* ++ * Copyright (C) 2014 Broadcom Corporation ++ * ++ * 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 version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "clk-iproc.h" ++ ++#define SB2_GEN_PLL_CTRL_1_OFFSET 0x04 ++#define SB2_GEN_PLL_CTRL_3_OFFSET 0x0C ++#define SB2_GEN_PLL_CTRL_5_OFFSET 0x14 ++#define SB2_GEN_PLL_CTRL_1_PDIV_R 27 ++#define SB2_GEN_PLL_CTRL_3_NDIV_INT_R 20 ++#define SB2_GEN_PLL_CTRL_5_CH1_MDIV_R 8 ++#define SB2_GEN_PLL_CTRL_1_PDIV_WIDTH 4 ++#define SB2_GEN_PLL_CTRL_3_NDIV_INT_WIDTH 10 ++#define SB2_GEN_PLL_CTRL_5_CH1_MDIV_WIDTH 8 ++ ++#define GEN_PLL_CTRL1_OFFSET 0x4 ++#define GEN_PLL_CTRL2_OFFSET 0x8 ++#define GEN_PLL_CTRL1_NDIV_INT_R 0 ++#define GEN_PLL_CTRL1_NDIV_INT_WIDTH 10 ++#define GEN_PLL_CTRL1_PDIV_R 10 ++#define GEN_PLL_CTRL2_CH3_MDIV_R 8 ++#define GEN_PLL_CTRL2_CH3_MDIV_WIDTH 8 ++#define GEN_PLL_CTRL1_PDIV_WIDTH_3 3 ++#define GEN_PLL_CTRL1_PDIV_WIDTH_4 4 ++ ++ ++struct iproc_gen_pll { ++ struct clk_hw hw; ++ void __iomem *base; ++ unsigned long rate; ++}; ++ ++#define to_iproc_gen_pll(phw) container_of(phw, struct iproc_gen_pll, hw) ++ ++static u32 genpll_pdiv_width; ++ ++static unsigned long iproc_axi_clk_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ uint32_t ndiv, mdiv, pdiv; ++ struct iproc_gen_pll *pll = to_iproc_gen_pll(hw); ++ ++ ++ ndiv = readl(pll->base + GEN_PLL_CTRL1_OFFSET) >> ++ GEN_PLL_CTRL1_NDIV_INT_R; ++ ndiv &= (1 << GEN_PLL_CTRL1_NDIV_INT_WIDTH) - 1; ++ if (ndiv == 0) ++ ndiv = 1 << GEN_PLL_CTRL1_NDIV_INT_WIDTH; ++ ++ pdiv = readl(pll->base + GEN_PLL_CTRL1_OFFSET) >> GEN_PLL_CTRL1_PDIV_R; ++ pdiv &= (1 << genpll_pdiv_width) -1; ++ if (pdiv == 0) ++ pdiv = 1 << genpll_pdiv_width; ++ ++ mdiv = readl(pll->base + GEN_PLL_CTRL2_OFFSET) >> ++ GEN_PLL_CTRL2_CH3_MDIV_R; ++ mdiv &= (1 << GEN_PLL_CTRL2_CH3_MDIV_WIDTH) - 1; ++ if (mdiv == 0) ++ mdiv = 1 << GEN_PLL_CTRL2_CH3_MDIV_WIDTH; ++ ++ pll->rate = parent_rate * ndiv / pdiv / mdiv; ++ return pll->rate; ++} ++ ++static unsigned long iproc_sb2_axi_clk_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ uint32_t ndiv, mdiv, pdiv; ++ struct iproc_gen_pll *pll = to_iproc_gen_pll(hw); ++ ++ ndiv = readl(pll->base + SB2_GEN_PLL_CTRL_3_OFFSET) >> ++ SB2_GEN_PLL_CTRL_3_NDIV_INT_R; ++ ndiv &= (1 << SB2_GEN_PLL_CTRL_3_NDIV_INT_WIDTH) - 1; ++ ++ mdiv = readl(pll->base + SB2_GEN_PLL_CTRL_5_OFFSET) >> ++ SB2_GEN_PLL_CTRL_5_CH1_MDIV_R; ++ mdiv &= (1 << SB2_GEN_PLL_CTRL_5_CH1_MDIV_WIDTH) - 1; ++ ++ pdiv = readl(pll->base + SB2_GEN_PLL_CTRL_1_OFFSET) >> ++ SB2_GEN_PLL_CTRL_1_PDIV_R; ++ pdiv &= (1 << SB2_GEN_PLL_CTRL_1_PDIV_WIDTH) - 1; ++ ++ pll->rate = parent_rate * ndiv / pdiv / mdiv; ++ return pll->rate; ++} ++ ++ ++static struct clk_ops iproc_axi_clk_ops = { ++ .recalc_rate = iproc_axi_clk_recalc_rate, ++}; ++ ++void __init xgs_iproc_axi_clk_setup(struct device_node *node) ++{ ++ int ret; ++ struct clk *clk; ++ struct iproc_gen_pll *pll; ++ struct clk_init_data init; ++ const char *parent_name; ++ ++ pll = kzalloc(sizeof(*pll), GFP_KERNEL); ++ if (WARN_ON(!pll)) ++ return; ++ ++ pll->base = of_iomap(node, 0); ++ if (WARN_ON(!pll->base)) ++ goto err_free_pll; ++ ++ init.name = node->name; ++ if ( of_device_is_compatible(node, "axi-clk-sb2") ) ++ iproc_axi_clk_ops.recalc_rate = iproc_sb2_axi_clk_recalc_rate; ++ if ( of_device_is_compatible(node, "axi-clk-hx4") || ++ of_device_is_compatible(node, "axi-clk-hr2") ) ++ genpll_pdiv_width = GEN_PLL_CTRL1_PDIV_WIDTH_3; ++ else ++ genpll_pdiv_width = GEN_PLL_CTRL1_PDIV_WIDTH_4; ++ ++ init.ops = &iproc_axi_clk_ops; ++ init.flags = 0; ++ parent_name = of_clk_get_parent_name(node, 0); ++ init.parent_names = (parent_name ? &parent_name : NULL); ++ init.num_parents = (parent_name ? 1 : 0); ++ pll->hw.init = &init; ++ ++ clk = clk_register(NULL, &pll->hw); ++ if (WARN_ON(IS_ERR(clk))) ++ goto err_iounmap; ++ ++ ret = of_clk_add_provider(node, of_clk_src_simple_get, clk); ++ if (WARN_ON(ret)) ++ goto err_clk_unregister; ++ ++ return; ++ ++err_clk_unregister: ++ clk_unregister(clk); ++err_iounmap: ++ iounmap(pll->base); ++err_free_pll: ++ kfree(pll); ++} ++ ++CLK_OF_DECLARE(xgs_iproc_axi_clk, "brcm,xgs-iproc-axi-clk", ++ xgs_iproc_axi_clk_setup); ++ ++ ++static void __init xgs_iproc_armpll_init(struct device_node *node) ++{ ++ iproc_armpll_setup(node); ++} ++CLK_OF_DECLARE(xgs_iproc_armpll, "brcm,xgs-iproc-armpll", ++ xgs_iproc_armpll_init); +\ No newline at end of file +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/dma/Kconfig b/drivers/dma/Kconfig +--- a/drivers/dma/Kconfig 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/dma/Kconfig 2017-11-09 17:53:27.047177000 +0800 +@@ -397,6 +397,14 @@ config PL330_DMA + You need to provide platform specific settings via + platform_data for a dma-pl330 device. + ++config XGS_IPROC_DMA330_DMA ++ tristate "DMA API Driver for XGS IPROC DMA330" ++ select DMA_ENGINE ++ depends on ARM_AMBA ++ help ++ Support the DMA engine for BRCM IPROC CoreLink ++ DMA Controller (DMA-330). ++ + config PXA_DMA + bool "PXA DMA support" + depends on (ARCH_MMP || ARCH_PXA) +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/dma/Makefile b/drivers/dma/Makefile +--- a/drivers/dma/Makefile 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/dma/Makefile 2017-11-09 17:53:27.048171000 +0800 +@@ -50,6 +50,7 @@ obj-$(CONFIG_MX3_IPU) += ipu/ + obj-$(CONFIG_NBPFAXI_DMA) += nbpfaxi.o + obj-$(CONFIG_PCH_DMA) += pch_dma.o + obj-$(CONFIG_PL330_DMA) += pl330.o ++obj-$(CONFIG_XGS_IPROC_DMA330_DMA) += iproc-dma330.o + obj-$(CONFIG_PPC_BESTCOMM) += bestcomm/ + obj-$(CONFIG_PXA_DMA) += pxa_dma.o + obj-$(CONFIG_QCOM_BAM_DMA) += qcom_bam_dma.o +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/dma/iproc-dma330.c b/drivers/dma/iproc-dma330.c +--- a/drivers/dma/iproc-dma330.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/dma/iproc-dma330.c 2017-11-09 17:53:27.192174000 +0800 +@@ -0,0 +1,3067 @@ ++/* ++ * BRCM IPROC DMA330 support ++ * ++ * This driver, modified from pl330.c, supports CoreLink DMA Controller ++ * (DMA-330). ++ * ++ * Copyright (C) 2016 Broadcom Corporation ++ * ++ * Copyright (C) 2010 Samsung Electronics Co. Ltd. ++ * Jaswinder Singh ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "dmaengine.h" ++#define DMA330_MAX_CHAN 8 ++#define DMA330_MAX_IRQS 32 ++#define DMA330_MAX_PERI 32 ++ ++struct dma_dma330_platdata { ++ u8 nr_valid_peri; ++ u8 *peri_id; ++ dma_cap_mask_t cap_mask; ++ unsigned mcbuf_sz; ++}; ++ ++enum dma330_cachectrl { ++ CCTRL0, /* Noncacheable and nonbufferable */ ++ CCTRL1, /* Bufferable only */ ++ CCTRL2, /* Cacheable, but do not allocate */ ++ CCTRL3, /* Cacheable and bufferable, but do not allocate */ ++ INVALID1, /* AWCACHE = 0x1000 */ ++ INVALID2, ++ CCTRL6, /* Cacheable write-through, allocate on writes only */ ++ CCTRL7, /* Cacheable write-back, allocate on writes only */ ++}; ++ ++enum dma330_byteswap { ++ SWAP_NO, ++ SWAP_2, ++ SWAP_4, ++ SWAP_8, ++ SWAP_16, ++}; ++ ++/* Register and Bit field Definitions */ ++#define DS 0x0 ++#define DS_ST_STOP 0x0 ++#define DS_ST_EXEC 0x1 ++#define DS_ST_CMISS 0x2 ++#define DS_ST_UPDTPC 0x3 ++#define DS_ST_WFE 0x4 ++#define DS_ST_ATBRR 0x5 ++#define DS_ST_QBUSY 0x6 ++#define DS_ST_WFP 0x7 ++#define DS_ST_KILL 0x8 ++#define DS_ST_CMPLT 0x9 ++#define DS_ST_FLTCMP 0xe ++#define DS_ST_FAULT 0xf ++ ++#define DPC 0x4 ++#define INTEN 0x20 ++#define ES 0x24 ++#define INTSTATUS 0x28 ++#define INTCLR 0x2c ++#define FSM 0x30 ++#define FSC 0x34 ++#define FTM 0x38 ++ ++#define _FTC 0x40 ++#define FTC(n) (_FTC + (n)*0x4) ++ ++#define _CS 0x100 ++#define CS(n) (_CS + (n)*0x8) ++#define CS_CNS (1 << 21) ++ ++#define _CPC 0x104 ++#define CPC(n) (_CPC + (n)*0x8) ++ ++#define _SA 0x400 ++#define SA(n) (_SA + (n)*0x20) ++ ++#define _DA 0x404 ++#define DA(n) (_DA + (n)*0x20) ++ ++#define _CC 0x408 ++#define CC(n) (_CC + (n)*0x20) ++ ++#define CC_SRCINC (1 << 0) ++#define CC_DSTINC (1 << 14) ++#define CC_SRCPRI (1 << 8) ++#define CC_DSTPRI (1 << 22) ++#define CC_SRCNS (1 << 9) ++#define CC_DSTNS (1 << 23) ++#define CC_SRCIA (1 << 10) ++#define CC_DSTIA (1 << 24) ++#define CC_SRCBRSTLEN_SHFT 4 ++#define CC_DSTBRSTLEN_SHFT 18 ++#define CC_SRCBRSTSIZE_SHFT 1 ++#define CC_DSTBRSTSIZE_SHFT 15 ++#define CC_SRCCCTRL_SHFT 11 ++#define CC_SRCCCTRL_MASK 0x7 ++#define CC_DSTCCTRL_SHFT 25 ++#define CC_DRCCCTRL_MASK 0x7 ++#define CC_SWAP_SHFT 28 ++ ++#define _LC0 0x40c ++#define LC0(n) (_LC0 + (n)*0x20) ++ ++#define _LC1 0x410 ++#define LC1(n) (_LC1 + (n)*0x20) ++ ++#define DBGSTATUS 0xd00 ++#define DBG_BUSY (1 << 0) ++ ++#define DBGCMD 0xd04 ++#define DBGINST0 0xd08 ++#define DBGINST1 0xd0c ++ ++#define CR0 0xe00 ++#define CR1 0xe04 ++#define CR2 0xe08 ++#define CR3 0xe0c ++#define CR4 0xe10 ++#define CRD 0xe14 ++ ++#define PERIPH_ID 0xfe0 ++#define PERIPH_REV_SHIFT 20 ++#define PERIPH_REV_MASK 0xf ++#define PERIPH_REV_R0P0 0 ++#define PERIPH_REV_R1P0 1 ++#define PERIPH_REV_R1P1 2 ++ ++#define CR0_PERIPH_REQ_SET (1 << 0) ++#define CR0_BOOT_EN_SET (1 << 1) ++#define CR0_BOOT_MAN_NS (1 << 2) ++#define CR0_NUM_CHANS_SHIFT 4 ++#define CR0_NUM_CHANS_MASK 0x7 ++#define CR0_NUM_PERIPH_SHIFT 12 ++#define CR0_NUM_PERIPH_MASK 0x1f ++#define CR0_NUM_EVENTS_SHIFT 17 ++#define CR0_NUM_EVENTS_MASK 0x1f ++ ++#define CR1_ICACHE_LEN_SHIFT 0 ++#define CR1_ICACHE_LEN_MASK 0x7 ++#define CR1_NUM_ICACHELINES_SHIFT 4 ++#define CR1_NUM_ICACHELINES_MASK 0xf ++ ++#define CRD_DATA_WIDTH_SHIFT 0 ++#define CRD_DATA_WIDTH_MASK 0x7 ++#define CRD_WR_CAP_SHIFT 4 ++#define CRD_WR_CAP_MASK 0x7 ++#define CRD_WR_Q_DEP_SHIFT 8 ++#define CRD_WR_Q_DEP_MASK 0xf ++#define CRD_RD_CAP_SHIFT 12 ++#define CRD_RD_CAP_MASK 0x7 ++#define CRD_RD_Q_DEP_SHIFT 16 ++#define CRD_RD_Q_DEP_MASK 0xf ++#define CRD_DATA_BUFF_SHIFT 20 ++#define CRD_DATA_BUFF_MASK 0x3ff ++ ++#define PART 0x330 ++#define DESIGNER 0x41 ++#define REVISION 0x2 ++#define INTEG_CFG 0x0 ++#define PERIPH_ID_VAL ((PART << 0) | (DESIGNER << 12) | (REVISION << 20)) ++ ++#define DMA330_STATE_STOPPED (1 << 0) ++#define DMA330_STATE_EXECUTING (1 << 1) ++#define DMA330_STATE_WFE (1 << 2) ++#define DMA330_STATE_FAULTING (1 << 3) ++#define DMA330_STATE_COMPLETING (1 << 4) ++#define DMA330_STATE_WFP (1 << 5) ++#define DMA330_STATE_KILLING (1 << 6) ++#define DMA330_STATE_FAULT_COMPLETING (1 << 7) ++#define DMA330_STATE_CACHEMISS (1 << 8) ++#define DMA330_STATE_UPDTPC (1 << 9) ++#define DMA330_STATE_ATBARRIER (1 << 10) ++#define DMA330_STATE_QUEUEBUSY (1 << 11) ++#define DMA330_STATE_INVALID (1 << 15) ++ ++#define DMA330_STABLE_STATES (DMA330_STATE_STOPPED | DMA330_STATE_EXECUTING \ ++ | DMA330_STATE_WFE | DMA330_STATE_FAULTING) ++ ++#define CMD_DMAADDH 0x54 ++#define CMD_DMAEND 0x00 ++#define CMD_DMAFLUSHP 0x35 ++#define CMD_DMAGO 0xa0 ++#define CMD_DMALD 0x04 ++#define CMD_DMALDP 0x25 ++#define CMD_DMALP 0x20 ++#define CMD_DMALPEND 0x28 ++#define CMD_DMAKILL 0x01 ++#define CMD_DMAMOV 0xbc ++#define CMD_DMANOP 0x18 ++#define CMD_DMARMB 0x12 ++#define CMD_DMASEV 0x34 ++#define CMD_DMAST 0x08 ++#define CMD_DMASTP 0x29 ++#define CMD_DMASTZ 0x0c ++#define CMD_DMAWFE 0x36 ++#define CMD_DMAWFP 0x30 ++#define CMD_DMAWMB 0x13 ++ ++#define SZ_DMAADDH 3 ++#define SZ_DMAEND 1 ++#define SZ_DMAFLUSHP 2 ++#define SZ_DMALD 1 ++#define SZ_DMALDP 2 ++#define SZ_DMALP 2 ++#define SZ_DMALPEND 2 ++#define SZ_DMAKILL 1 ++#define SZ_DMAMOV 6 ++#define SZ_DMANOP 1 ++#define SZ_DMARMB 1 ++#define SZ_DMASEV 2 ++#define SZ_DMAST 1 ++#define SZ_DMASTP 2 ++#define SZ_DMASTZ 1 ++#define SZ_DMAWFE 2 ++#define SZ_DMAWFP 2 ++#define SZ_DMAWMB 1 ++#define SZ_DMAGO 6 ++ ++#define BRST_LEN(ccr) ((((ccr) >> CC_SRCBRSTLEN_SHFT) & 0xf) + 1) ++#define BRST_SIZE(ccr) (1 << (((ccr) >> CC_SRCBRSTSIZE_SHFT) & 0x7)) ++ ++#define BYTE_TO_BURST(b, ccr) ((b) / BRST_SIZE(ccr) / BRST_LEN(ccr)) ++#define BURST_TO_BYTE(c, ccr) ((c) * BRST_SIZE(ccr) * BRST_LEN(ccr)) ++ ++/* ++ * With 256 bytes, we can do more than 2.5MB and 5MB xfers per req ++ * at 1byte/burst for P<->M and M<->M respectively. ++ * For typical scenario, at 1word/burst, 10MB and 20MB xfers per req ++ * should be enough for P<->M and M<->M respectively. ++ */ ++#define MCODE_BUFF_PER_REQ 256 ++ ++/* Use this _only_ to wait on transient states */ ++#define UNTIL(t, s) while (!(_state(t) & (s))) cpu_relax(); ++ ++#ifdef DMA330_DEBUG_MCGEN ++static unsigned cmd_line; ++#define DMA330_DBGCMD_DUMP(off, x...) do { \ ++ printk("%x:", cmd_line); \ ++ printk(x); \ ++ cmd_line += off; \ ++ } while (0) ++#define DMA330_DBGMC_START(addr) (cmd_line = addr) ++#else ++#define DMA330_DBGCMD_DUMP(off, x...) do {} while (0) ++#define DMA330_DBGMC_START(addr) do {} while (0) ++#endif ++ ++/* The number of default descriptors */ ++ ++#define NR_DEFAULT_DESC 16 ++ ++/* Delay for runtime PM autosuspend, ms */ ++#define DMA330_AUTOSUSPEND_DELAY 20 ++ ++/* Populated by the DMA330 core driver for DMA API driver's info */ ++struct dma330_config { ++ u32 periph_id; ++#define DMAC_MODE_NS (1 << 0) ++ unsigned int mode; ++ unsigned int data_bus_width:10; /* In number of bits */ ++ unsigned int data_buf_dep:11; ++ unsigned int num_chan:4; ++ unsigned int num_peri:6; ++ u32 peri_ns; ++ unsigned int num_events:6; ++ u32 irq_ns; ++}; ++ ++/** ++ * Request Configuration. ++ * The DMA330 core does not modify this and uses the last ++ * working configuration if the request doesn't provide any. ++ * ++ * The Client may want to provide this info only for the ++ * first request and a request with new settings. ++ */ ++struct dma330_reqcfg { ++ /* Address Incrementing */ ++ unsigned dst_inc:1; ++ unsigned src_inc:1; ++ ++ /* ++ * For now, the SRC & DST protection levels ++ * and burst size/length are assumed same. ++ */ ++ bool nonsecure; ++ bool privileged; ++ bool insnaccess; ++ unsigned brst_len:5; ++ unsigned brst_size:3; /* in power of 2 */ ++ ++ enum dma330_cachectrl dcctl; ++ enum dma330_cachectrl scctl; ++ enum dma330_byteswap swap; ++ struct dma330_config *pcfg; ++}; ++ ++/* ++ * One cycle of DMAC operation. ++ * There may be more than one xfer in a request. ++ */ ++struct dma330_xfer { ++ u32 src_addr; ++ u32 dst_addr; ++ /* Size to xfer */ ++ u32 bytes; ++}; ++ ++/* The xfer callbacks are made with one of these arguments. */ ++enum dma330_op_err { ++ /* The all xfers in the request were success. */ ++ DMA330_ERR_NONE, ++ /* If req aborted due to global error. */ ++ DMA330_ERR_ABORT, ++ /* If req failed due to problem with Channel. */ ++ DMA330_ERR_FAIL, ++}; ++ ++enum dmamov_dst { ++ SAR = 0, ++ CCR, ++ DAR, ++}; ++ ++enum dma330_dst { ++ SRC = 0, ++ DST, ++}; ++ ++enum dma330_cond { ++ SINGLE, ++ BURST, ++ ALWAYS, ++}; ++ ++struct dma_dma330_desc; ++ ++struct _dma330_req { ++ u32 mc_bus; ++ void *mc_cpu; ++ struct dma_dma330_desc *desc; ++}; ++ ++/* ToBeDone for tasklet */ ++struct _dma330_tbd { ++ bool reset_dmac; ++ bool reset_mngr; ++ u8 reset_chan; ++}; ++ ++/* A DMAC Thread */ ++struct dma330_thread { ++ u8 id; ++ int ev; ++ /* If the channel is not yet acquired by any client */ ++ bool free; ++ /* Parent DMAC */ ++ struct dma330_dmac *dmac; ++ /* Only two at a time */ ++ struct _dma330_req req[2]; ++ /* Index of the last enqueued request */ ++ unsigned lstenq; ++ /* Index of the last submitted request or -1 if the DMA is stopped */ ++ int req_running; ++}; ++ ++enum dma330_dmac_state { ++ UNINIT, ++ INIT, ++ DYING, ++}; ++ ++enum desc_status { ++ /* In the DMAC pool */ ++ FREE, ++ /* ++ * Allocated to some channel during prep_xxx ++ * Also may be sitting on the work_list. ++ */ ++ PREP, ++ /* ++ * Sitting on the work_list and already submitted ++ * to the DMA330 core. Not more than two descriptors ++ * of a channel can be BUSY at any time. ++ */ ++ BUSY, ++ /* ++ * Sitting on the channel work_list but xfer done ++ * by DMA330 core ++ */ ++ DONE, ++}; ++ ++struct dma_dma330_chan { ++ /* Schedule desc completion */ ++ struct tasklet_struct task; ++ ++ /* DMA-Engine Channel */ ++ struct dma_chan chan; ++ ++ /* List of submitted descriptors */ ++ struct list_head submitted_list; ++ /* List of issued descriptors */ ++ struct list_head work_list; ++ /* List of completed descriptors */ ++ struct list_head completed_list; ++ ++ /* Pointer to the DMAC that manages this channel, ++ * NULL if the channel is available to be acquired. ++ * As the parent, this DMAC also provides descriptors ++ * to the channel. ++ */ ++ struct dma330_dmac *dmac; ++ ++ /* To protect channel manipulation */ ++ spinlock_t lock; ++ ++ /* ++ * Hardware channel thread of DMA330 DMAC. NULL if the channel is ++ * available. ++ */ ++ struct dma330_thread *thread; ++ ++ /* For D-to-M and M-to-D channels */ ++ int burst_sz; /* the peripheral fifo width */ ++ int burst_len; /* the number of burst */ ++ dma_addr_t fifo_addr; ++ ++ /* for cyclic capability */ ++ bool cyclic; ++}; ++ ++struct dma330_dmac { ++ /* DMA-Engine Device */ ++ struct dma_device ddma; ++ ++ /* Holds info about sg limitations */ ++ struct device_dma_parameters dma_parms; ++ ++ /* Pool of descriptors available for the DMAC's channels */ ++ struct list_head desc_pool; ++ /* To protect desc_pool manipulation */ ++ spinlock_t pool_lock; ++ ++ /* Size of MicroCode buffers for each channel. */ ++ unsigned mcbufsz; ++ /* ioremap'ed address of DMA330 registers. */ ++ void __iomem *base; ++ /* Populated by the DMA330 core driver during dma330_add */ ++ struct dma330_config pcfg; ++ ++ spinlock_t lock; ++ /* Maximum possible events/irqs */ ++ int events[32]; ++ /* BUS address of MicroCode buffer */ ++ dma_addr_t mcode_bus; ++ /* CPU address of MicroCode buffer */ ++ void *mcode_cpu; ++ /* List of all Channel threads */ ++ struct dma330_thread *channels; ++ /* Pointer to the MANAGER thread */ ++ struct dma330_thread *manager; ++ /* To handle bad news in interrupt */ ++ struct tasklet_struct tasks; ++ struct _dma330_tbd dmac_tbd; ++ /* State of DMAC operation */ ++ enum dma330_dmac_state state; ++ /* Holds list of reqs with due callbacks */ ++ struct list_head req_done; ++ ++ /* Peripheral channels connected to this DMAC */ ++ unsigned int num_peripherals; ++ struct dma_dma330_chan *peripherals; /* keep at end */ ++}; ++ ++struct dma_dma330_desc { ++ /* To attach to a queue as child */ ++ struct list_head node; ++ ++ /* Descriptor for the DMA Engine API */ ++ struct dma_async_tx_descriptor txd; ++ ++ /* Xfer for DMA330 core */ ++ struct dma330_xfer px; ++ ++ struct dma330_reqcfg rqcfg; ++ ++ enum desc_status status; ++ ++ int bytes_requested; ++ bool last; ++ ++ /* The channel which currently holds this desc */ ++ struct dma_dma330_chan *pchan; ++ ++ enum dma_transfer_direction rqtype; ++ /* Index of peripheral for the xfer. */ ++ unsigned peri:5; ++ /* Hook to attach to DMAC's list of reqs with due callback */ ++ struct list_head rqd; ++}; ++ ++struct _xfer_spec { ++ u32 ccr; ++ struct dma_dma330_desc *desc; ++}; ++ ++static inline bool _queue_empty(struct dma330_thread *thrd) ++{ ++ return thrd->req[0].desc == NULL && thrd->req[1].desc == NULL; ++} ++ ++static inline bool _queue_full(struct dma330_thread *thrd) ++{ ++ return thrd->req[0].desc != NULL && thrd->req[1].desc != NULL; ++} ++ ++static inline bool is_manager(struct dma330_thread *thrd) ++{ ++ return thrd->dmac->manager == thrd; ++} ++ ++/* If manager of the thread is in Non-Secure mode */ ++static inline bool _manager_ns(struct dma330_thread *thrd) ++{ ++ return (thrd->dmac->pcfg.mode & DMAC_MODE_NS) ? true : false; ++} ++ ++static inline u32 get_revision(u32 periph_id) ++{ ++ return (periph_id >> PERIPH_REV_SHIFT) & PERIPH_REV_MASK; ++} ++ ++static inline u32 _emit_ADDH(unsigned dry_run, u8 buf[], ++ enum dma330_dst da, u16 val) ++{ ++ if (dry_run) ++ return SZ_DMAADDH; ++ ++ buf[0] = CMD_DMAADDH; ++ buf[0] |= (da << 1); ++ *((__le16 *)&buf[1]) = cpu_to_le16(val); ++ ++ DMA330_DBGCMD_DUMP(SZ_DMAADDH, "\tDMAADDH %s %u\n", ++ da == 1 ? "DA" : "SA", val); ++ ++ return SZ_DMAADDH; ++} ++ ++static inline u32 _emit_END(unsigned dry_run, u8 buf[]) ++{ ++ if (dry_run) ++ return SZ_DMAEND; ++ ++ buf[0] = CMD_DMAEND; ++ ++ DMA330_DBGCMD_DUMP(SZ_DMAEND, "\tDMAEND\n"); ++ ++ return SZ_DMAEND; ++} ++ ++static inline u32 _emit_FLUSHP(unsigned dry_run, u8 buf[], u8 peri) ++{ ++ if (dry_run) ++ return SZ_DMAFLUSHP; ++ ++ buf[0] = CMD_DMAFLUSHP; ++ ++ peri &= 0x1f; ++ peri <<= 3; ++ buf[1] = peri; ++ ++ DMA330_DBGCMD_DUMP(SZ_DMAFLUSHP, "\tDMAFLUSHP %u\n", peri >> 3); ++ ++ return SZ_DMAFLUSHP; ++} ++ ++static inline u32 _emit_LD(unsigned dry_run, u8 buf[], enum dma330_cond cond) ++{ ++ if (dry_run) ++ return SZ_DMALD; ++ ++ buf[0] = CMD_DMALD; ++ ++ if (cond == SINGLE) ++ buf[0] |= (0 << 1) | (1 << 0); ++ else if (cond == BURST) ++ buf[0] |= (1 << 1) | (1 << 0); ++ ++ DMA330_DBGCMD_DUMP(SZ_DMALD, "\tDMALD%c\n", ++ cond == SINGLE ? 'S' : (cond == BURST ? 'B' : 'A')); ++ ++ return SZ_DMALD; ++} ++ ++static inline u32 _emit_LDP(unsigned dry_run, u8 buf[], ++ enum dma330_cond cond, u8 peri) ++{ ++ if (dry_run) ++ return SZ_DMALDP; ++ ++ buf[0] = CMD_DMALDP; ++ ++ if (cond == BURST) ++ buf[0] |= (1 << 1); ++ ++ peri &= 0x1f; ++ peri <<= 3; ++ buf[1] = peri; ++ ++ DMA330_DBGCMD_DUMP(SZ_DMALDP, "\tDMALDP%c %u\n", ++ cond == SINGLE ? 'S' : 'B', peri >> 3); ++ ++ return SZ_DMALDP; ++} ++ ++static inline u32 _emit_LP(unsigned dry_run, u8 buf[], ++ unsigned loop, u8 cnt) ++{ ++ if (dry_run) ++ return SZ_DMALP; ++ ++ buf[0] = CMD_DMALP; ++ ++ if (loop) ++ buf[0] |= (1 << 1); ++ ++ cnt--; /* DMAC increments by 1 internally */ ++ buf[1] = cnt; ++ ++ DMA330_DBGCMD_DUMP(SZ_DMALP, "\tDMALP_%c %u\n", loop ? '1' : '0', cnt); ++ ++ return SZ_DMALP; ++} ++ ++struct _arg_LPEND { ++ enum dma330_cond cond; ++ bool forever; ++ unsigned loop; ++ u8 bjump; ++}; ++ ++static inline u32 _emit_LPEND(unsigned dry_run, u8 buf[], ++ const struct _arg_LPEND *arg) ++{ ++ enum dma330_cond cond = arg->cond; ++ bool forever = arg->forever; ++ unsigned loop = arg->loop; ++ u8 bjump = arg->bjump; ++ ++ if (dry_run) ++ return SZ_DMALPEND; ++ ++ buf[0] = CMD_DMALPEND; ++ ++ if (loop) ++ buf[0] |= (1 << 2); ++ ++ if (!forever) ++ buf[0] |= (1 << 4); ++ ++ if (cond == SINGLE) ++ buf[0] |= (0 << 1) | (1 << 0); ++ else if (cond == BURST) ++ buf[0] |= (1 << 1) | (1 << 0); ++ ++ buf[1] = bjump; ++ ++ DMA330_DBGCMD_DUMP(SZ_DMALPEND, "\tDMALP%s%c_%c bjmpto_%x\n", ++ forever ? "FE" : "END", ++ cond == SINGLE ? 'S' : (cond == BURST ? 'B' : 'A'), ++ loop ? '1' : '0', ++ bjump); ++ ++ return SZ_DMALPEND; ++} ++ ++static inline u32 _emit_KILL(unsigned dry_run, u8 buf[]) ++{ ++ if (dry_run) ++ return SZ_DMAKILL; ++ ++ buf[0] = CMD_DMAKILL; ++ ++ return SZ_DMAKILL; ++} ++ ++static inline u32 _emit_MOV(unsigned dry_run, u8 buf[], ++ enum dmamov_dst dst, u32 val) ++{ ++ if (dry_run) ++ return SZ_DMAMOV; ++ ++ buf[0] = CMD_DMAMOV; ++ buf[1] = dst; ++ *((__le32 *)&buf[2]) = cpu_to_le32(val); ++ ++ DMA330_DBGCMD_DUMP(SZ_DMAMOV, "\tDMAMOV %s 0x%x\n", ++ dst == SAR ? "SAR" : (dst == DAR ? "DAR" : "CCR"), val); ++ ++ return SZ_DMAMOV; ++} ++ ++static inline u32 _emit_NOP(unsigned dry_run, u8 buf[]) ++{ ++ if (dry_run) ++ return SZ_DMANOP; ++ ++ buf[0] = CMD_DMANOP; ++ ++ DMA330_DBGCMD_DUMP(SZ_DMANOP, "\tDMANOP\n"); ++ ++ return SZ_DMANOP; ++} ++ ++static inline u32 _emit_RMB(unsigned dry_run, u8 buf[]) ++{ ++ if (dry_run) ++ return SZ_DMARMB; ++ ++ buf[0] = CMD_DMARMB; ++ ++ DMA330_DBGCMD_DUMP(SZ_DMARMB, "\tDMARMB\n"); ++ ++ return SZ_DMARMB; ++} ++ ++static inline u32 _emit_SEV(unsigned dry_run, u8 buf[], u8 ev) ++{ ++ if (dry_run) ++ return SZ_DMASEV; ++ ++ buf[0] = CMD_DMASEV; ++ ++ ev &= 0x1f; ++ ev <<= 3; ++ buf[1] = ev; ++ ++ DMA330_DBGCMD_DUMP(SZ_DMASEV, "\tDMASEV %u\n", ev >> 3); ++ ++ return SZ_DMASEV; ++} ++ ++static inline u32 _emit_ST(unsigned dry_run, u8 buf[], enum dma330_cond cond) ++{ ++ if (dry_run) ++ return SZ_DMAST; ++ ++ buf[0] = CMD_DMAST; ++ ++ if (cond == SINGLE) ++ buf[0] |= (0 << 1) | (1 << 0); ++ else if (cond == BURST) ++ buf[0] |= (1 << 1) | (1 << 0); ++ ++ DMA330_DBGCMD_DUMP(SZ_DMAST, "\tDMAST%c\n", ++ cond == SINGLE ? 'S' : (cond == BURST ? 'B' : 'A')); ++ ++ return SZ_DMAST; ++} ++ ++static inline u32 _emit_STP(unsigned dry_run, u8 buf[], ++ enum dma330_cond cond, u8 peri) ++{ ++ if (dry_run) ++ return SZ_DMASTP; ++ ++ buf[0] = CMD_DMASTP; ++ ++ if (cond == BURST) ++ buf[0] |= (1 << 1); ++ ++ peri &= 0x1f; ++ peri <<= 3; ++ buf[1] = peri; ++ ++ DMA330_DBGCMD_DUMP(SZ_DMASTP, "\tDMASTP%c %u\n", ++ cond == SINGLE ? 'S' : 'B', peri >> 3); ++ ++ return SZ_DMASTP; ++} ++ ++static inline u32 _emit_STZ(unsigned dry_run, u8 buf[]) ++{ ++ if (dry_run) ++ return SZ_DMASTZ; ++ ++ buf[0] = CMD_DMASTZ; ++ ++ DMA330_DBGCMD_DUMP(SZ_DMASTZ, "\tDMASTZ\n"); ++ ++ return SZ_DMASTZ; ++} ++ ++static inline u32 _emit_WFE(unsigned dry_run, u8 buf[], u8 ev, ++ unsigned invalidate) ++{ ++ if (dry_run) ++ return SZ_DMAWFE; ++ ++ buf[0] = CMD_DMAWFE; ++ ++ ev &= 0x1f; ++ ev <<= 3; ++ buf[1] = ev; ++ ++ if (invalidate) ++ buf[1] |= (1 << 1); ++ ++ DMA330_DBGCMD_DUMP(SZ_DMAWFE, "\tDMAWFE %u%s\n", ++ ev >> 3, invalidate ? ", I" : ""); ++ ++ return SZ_DMAWFE; ++} ++ ++static inline u32 _emit_WFP(unsigned dry_run, u8 buf[], ++ enum dma330_cond cond, u8 peri) ++{ ++ if (dry_run) ++ return SZ_DMAWFP; ++ ++ buf[0] = CMD_DMAWFP; ++ ++ if (cond == SINGLE) ++ buf[0] |= (0 << 1) | (0 << 0); ++ else if (cond == BURST) ++ buf[0] |= (1 << 1) | (0 << 0); ++ else ++ buf[0] |= (0 << 1) | (1 << 0); ++ ++ peri &= 0x1f; ++ peri <<= 3; ++ buf[1] = peri; ++ ++ DMA330_DBGCMD_DUMP(SZ_DMAWFP, "\tDMAWFP%c %u\n", ++ cond == SINGLE ? 'S' : (cond == BURST ? 'B' : 'P'), peri >> 3); ++ ++ return SZ_DMAWFP; ++} ++ ++static inline u32 _emit_WMB(unsigned dry_run, u8 buf[]) ++{ ++ if (dry_run) ++ return SZ_DMAWMB; ++ ++ buf[0] = CMD_DMAWMB; ++ ++ DMA330_DBGCMD_DUMP(SZ_DMAWMB, "\tDMAWMB\n"); ++ ++ return SZ_DMAWMB; ++} ++ ++struct _arg_GO { ++ u8 chan; ++ u32 addr; ++ unsigned ns; ++}; ++ ++static inline u32 _emit_GO(unsigned dry_run, u8 buf[], ++ const struct _arg_GO *arg) ++{ ++ u8 chan = arg->chan; ++ u32 addr = arg->addr; ++ unsigned ns = arg->ns; ++ ++ if (dry_run) ++ return SZ_DMAGO; ++ ++ buf[0] = CMD_DMAGO; ++ buf[0] |= (ns << 1); ++ ++ buf[1] = chan & 0x7; ++ ++ *((__le32 *)&buf[2]) = cpu_to_le32(addr); ++ ++ return SZ_DMAGO; ++} ++ ++#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) ++ ++/* Returns Time-Out */ ++static bool _until_dmac_idle(struct dma330_thread *thrd) ++{ ++ void __iomem *regs = thrd->dmac->base; ++ unsigned long loops = msecs_to_loops(5); ++ ++ do { ++ /* Until Manager is Idle */ ++ if (!(readl(regs + DBGSTATUS) & DBG_BUSY)) ++ break; ++ ++ cpu_relax(); ++ } while (--loops); ++ ++ if (!loops) ++ return true; ++ ++ return false; ++} ++ ++static inline void _execute_DBGINSN(struct dma330_thread *thrd, ++ u8 insn[], bool as_manager) ++{ ++ void __iomem *regs = thrd->dmac->base; ++ u32 val; ++ ++ val = (insn[0] << 16) | (insn[1] << 24); ++ if (!as_manager) { ++ val |= (1 << 0); ++ val |= (thrd->id << 8); /* Channel Number */ ++ } ++ writel(val, regs + DBGINST0); ++ ++ val = le32_to_cpu(*((__le32 *)&insn[2])); ++ writel(val, regs + DBGINST1); ++ ++ /* If timed out due to halted state-machine */ ++ if (_until_dmac_idle(thrd)) { ++ dev_err(thrd->dmac->ddma.dev, "DMAC halted!\n"); ++ return; ++ } ++ ++ /* Get going */ ++ writel(0, regs + DBGCMD); ++} ++ ++static inline u32 _state(struct dma330_thread *thrd) ++{ ++ void __iomem *regs = thrd->dmac->base; ++ u32 val; ++ ++ if (is_manager(thrd)) ++ val = readl(regs + DS) & 0xf; ++ else ++ val = readl(regs + CS(thrd->id)) & 0xf; ++ ++ switch (val) { ++ case DS_ST_STOP: ++ return DMA330_STATE_STOPPED; ++ case DS_ST_EXEC: ++ return DMA330_STATE_EXECUTING; ++ case DS_ST_CMISS: ++ return DMA330_STATE_CACHEMISS; ++ case DS_ST_UPDTPC: ++ return DMA330_STATE_UPDTPC; ++ case DS_ST_WFE: ++ return DMA330_STATE_WFE; ++ case DS_ST_FAULT: ++ return DMA330_STATE_FAULTING; ++ case DS_ST_ATBRR: ++ if (is_manager(thrd)) ++ return DMA330_STATE_INVALID; ++ else ++ return DMA330_STATE_ATBARRIER; ++ case DS_ST_QBUSY: ++ if (is_manager(thrd)) ++ return DMA330_STATE_INVALID; ++ else ++ return DMA330_STATE_QUEUEBUSY; ++ case DS_ST_WFP: ++ if (is_manager(thrd)) ++ return DMA330_STATE_INVALID; ++ else ++ return DMA330_STATE_WFP; ++ case DS_ST_KILL: ++ if (is_manager(thrd)) ++ return DMA330_STATE_INVALID; ++ else ++ return DMA330_STATE_KILLING; ++ case DS_ST_CMPLT: ++ if (is_manager(thrd)) ++ return DMA330_STATE_INVALID; ++ else ++ return DMA330_STATE_COMPLETING; ++ case DS_ST_FLTCMP: ++ if (is_manager(thrd)) ++ return DMA330_STATE_INVALID; ++ else ++ return DMA330_STATE_FAULT_COMPLETING; ++ default: ++ return DMA330_STATE_INVALID; ++ } ++} ++ ++static void _stop(struct dma330_thread *thrd) ++{ ++ void __iomem *regs = thrd->dmac->base; ++ u8 insn[6] = {0, 0, 0, 0, 0, 0}; ++ ++ if (_state(thrd) == DMA330_STATE_FAULT_COMPLETING) ++ UNTIL(thrd, DMA330_STATE_FAULTING | DMA330_STATE_KILLING); ++ ++ /* Return if nothing needs to be done */ ++ if (_state(thrd) == DMA330_STATE_COMPLETING ++ || _state(thrd) == DMA330_STATE_KILLING ++ || _state(thrd) == DMA330_STATE_STOPPED) ++ return; ++ ++ _emit_KILL(0, insn); ++ ++ /* Stop generating interrupts for SEV */ ++ writel(readl(regs + INTEN) & ~(1 << thrd->ev), regs + INTEN); ++ ++ _execute_DBGINSN(thrd, insn, is_manager(thrd)); ++} ++ ++/* Start doing req 'idx' of thread 'thrd' */ ++static bool _trigger(struct dma330_thread *thrd) ++{ ++ void __iomem *regs = thrd->dmac->base; ++ struct _dma330_req *req; ++ struct dma_dma330_desc *desc; ++ struct _arg_GO go; ++ unsigned ns; ++ u8 insn[6] = {0, 0, 0, 0, 0, 0}; ++ int idx; ++ ++ /* Return if already ACTIVE */ ++ if (_state(thrd) != DMA330_STATE_STOPPED) ++ return true; ++ ++ idx = 1 - thrd->lstenq; ++ if (thrd->req[idx].desc != NULL) { ++ req = &thrd->req[idx]; ++ } else { ++ idx = thrd->lstenq; ++ if (thrd->req[idx].desc != NULL) ++ req = &thrd->req[idx]; ++ else ++ req = NULL; ++ } ++ ++ /* Return if no request */ ++ if (!req) ++ return true; ++ ++ /* Return if req is running */ ++ if (idx == thrd->req_running) ++ return true; ++ ++ desc = req->desc; ++ ++ ns = desc->rqcfg.nonsecure ? 1 : 0; ++ ++ /* See 'Abort Sources' point-4 at Page 2-25 */ ++ if (_manager_ns(thrd) && !ns) ++ dev_info(thrd->dmac->ddma.dev, "%s:%d Recipe for ABORT!\n", ++ __func__, __LINE__); ++ ++ go.chan = thrd->id; ++ go.addr = req->mc_bus; ++ go.ns = ns; ++ _emit_GO(0, insn, &go); ++ ++ /* Set to generate interrupts for SEV */ ++ writel(readl(regs + INTEN) | (1 << thrd->ev), regs + INTEN); ++ ++ /* Only manager can execute GO */ ++ _execute_DBGINSN(thrd, insn, true); ++ ++ thrd->req_running = idx; ++ ++ return true; ++} ++ ++static bool _start(struct dma330_thread *thrd) ++{ ++ switch (_state(thrd)) { ++ case DMA330_STATE_FAULT_COMPLETING: ++ UNTIL(thrd, DMA330_STATE_FAULTING | DMA330_STATE_KILLING); ++ ++ if (_state(thrd) == DMA330_STATE_KILLING) ++ UNTIL(thrd, DMA330_STATE_STOPPED) ++ ++ case DMA330_STATE_FAULTING: ++ _stop(thrd); ++ ++ case DMA330_STATE_KILLING: ++ case DMA330_STATE_COMPLETING: ++ UNTIL(thrd, DMA330_STATE_STOPPED) ++ ++ case DMA330_STATE_STOPPED: ++ return _trigger(thrd); ++ ++ case DMA330_STATE_WFP: ++ case DMA330_STATE_QUEUEBUSY: ++ case DMA330_STATE_ATBARRIER: ++ case DMA330_STATE_UPDTPC: ++ case DMA330_STATE_CACHEMISS: ++ case DMA330_STATE_EXECUTING: ++ return true; ++ ++ case DMA330_STATE_WFE: /* For RESUME, nothing yet */ ++ default: ++ return false; ++ } ++} ++ ++static inline int _ldst_memtomem(unsigned dry_run, u8 buf[], ++ const struct _xfer_spec *pxs, int cyc) ++{ ++ int off = 0; ++ ++ while (cyc--) { ++ off += _emit_LD(dry_run, &buf[off], ALWAYS); ++ off += _emit_ST(dry_run, &buf[off], ALWAYS); ++ } ++ ++ return off; ++} ++ ++static inline int _ldst_devtomem(unsigned dry_run, u8 buf[], ++ const struct _xfer_spec *pxs, int cyc) ++{ ++ int off = 0; ++ ++ while (cyc--) { ++ off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->desc->peri); ++ off += _emit_LD(dry_run, &buf[off], ALWAYS); ++ off += _emit_STP(dry_run, &buf[off], SINGLE, pxs->desc->peri); ++ off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri); ++ } ++ ++ return off; ++} ++ ++static inline int _ldst_memtodev(unsigned dry_run, u8 buf[], ++ const struct _xfer_spec *pxs, int cyc) ++{ ++ int off = 0; ++ ++ while (cyc--) { ++ off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->desc->peri); ++ off += _emit_LD(dry_run, &buf[off], ALWAYS); ++ off += _emit_STP(dry_run, &buf[off], SINGLE, pxs->desc->peri); ++ off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri); ++ } ++ ++ return off; ++} ++ ++static int _bursts(unsigned dry_run, u8 buf[], ++ const struct _xfer_spec *pxs, int cyc) ++{ ++ int off = 0; ++ ++ switch (pxs->desc->rqtype) { ++ case DMA_MEM_TO_DEV: ++ off += _ldst_memtodev(dry_run, &buf[off], pxs, cyc); ++ break; ++ case DMA_DEV_TO_MEM: ++ off += _ldst_devtomem(dry_run, &buf[off], pxs, cyc); ++ break; ++ case DMA_MEM_TO_MEM: ++ off += _ldst_memtomem(dry_run, &buf[off], pxs, cyc); ++ break; ++ default: ++ off += 0x40000000; /* Scare off the Client */ ++ break; ++ } ++ ++ return off; ++} ++ ++/* Returns bytes consumed and updates bursts */ ++static inline int _loop(unsigned dry_run, u8 buf[], ++ unsigned long *bursts, const struct _xfer_spec *pxs) ++{ ++ int cyc, cycmax, szlp, szlpend, szbrst, off; ++ unsigned lcnt0, lcnt1, ljmp0, ljmp1; ++ struct _arg_LPEND lpend; ++ ++ if (*bursts == 1) ++ return _bursts(dry_run, buf, pxs, 1); ++ ++ /* Max iterations possible in DMALP is 256 */ ++ if (*bursts >= 256*256) { ++ lcnt1 = 256; ++ lcnt0 = 256; ++ cyc = *bursts / lcnt1 / lcnt0; ++ } else if (*bursts > 256) { ++ lcnt1 = 256; ++ lcnt0 = *bursts / lcnt1; ++ cyc = 1; ++ } else { ++ lcnt1 = *bursts; ++ lcnt0 = 0; ++ cyc = 1; ++ } ++ ++ szlp = _emit_LP(1, buf, 0, 0); ++ szbrst = _bursts(1, buf, pxs, 1); ++ ++ lpend.cond = ALWAYS; ++ lpend.forever = false; ++ lpend.loop = 0; ++ lpend.bjump = 0; ++ szlpend = _emit_LPEND(1, buf, &lpend); ++ ++ if (lcnt0) { ++ szlp *= 2; ++ szlpend *= 2; ++ } ++ ++ /* ++ * Max bursts that we can unroll due to limit on the ++ * size of backward jump that can be encoded in DMALPEND ++ * which is 8-bits and hence 255 ++ */ ++ cycmax = (255 - (szlp + szlpend)) / szbrst; ++ ++ cyc = (cycmax < cyc) ? cycmax : cyc; ++ ++ off = 0; ++ ++ if (lcnt0) { ++ off += _emit_LP(dry_run, &buf[off], 0, lcnt0); ++ ljmp0 = off; ++ } ++ ++ off += _emit_LP(dry_run, &buf[off], 1, lcnt1); ++ ljmp1 = off; ++ ++ off += _bursts(dry_run, &buf[off], pxs, cyc); ++ ++ lpend.cond = ALWAYS; ++ lpend.forever = false; ++ lpend.loop = 1; ++ lpend.bjump = off - ljmp1; ++ off += _emit_LPEND(dry_run, &buf[off], &lpend); ++ ++ if (lcnt0) { ++ lpend.cond = ALWAYS; ++ lpend.forever = false; ++ lpend.loop = 0; ++ lpend.bjump = off - ljmp0; ++ off += _emit_LPEND(dry_run, &buf[off], &lpend); ++ } ++ ++ *bursts = lcnt1 * cyc; ++ if (lcnt0) ++ *bursts *= lcnt0; ++ ++ return off; ++} ++ ++static inline int _req_loop(unsigned dry_run, u8 buf[], enum dma330_cond cond, ++ unsigned long *count, const struct _xfer_spec *pxs) ++{ ++ unsigned ljmp0; ++ struct _arg_LPEND lpend; ++ int off = 0; ++ ++ off += _emit_LP(dry_run, &buf[off], 0, *count); ++ ljmp0 = off; ++ ++ off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri); ++ off += _emit_LD(dry_run, &buf[off], cond); ++ off += _emit_STP(dry_run, &buf[off], cond, pxs->desc->peri); ++ ++ lpend.cond = cond; ++ lpend.forever = false; ++ lpend.loop = 0; ++ lpend.bjump = off - ljmp0; ++ off += _emit_LPEND(dry_run, &buf[off], &lpend); ++ ++ return off; ++} ++ ++static inline u32 _prepare_ccr(const struct dma330_reqcfg *rqc, ++ enum dma330_cond cond) ++{ ++ u32 ccr = 0; ++ ++ if (rqc->src_inc) ++ ccr |= CC_SRCINC; ++ ++ if (rqc->dst_inc) ++ ccr |= CC_DSTINC; ++ ++ /* We set same protection levels for Src and DST for now */ ++ if (rqc->privileged) ++ ccr |= CC_SRCPRI | CC_DSTPRI; ++ if (rqc->nonsecure) ++ ccr |= CC_SRCNS | CC_DSTNS; ++ if (rqc->insnaccess) ++ ccr |= CC_SRCIA | CC_DSTIA; ++ ++ if (cond != SINGLE) { ++ ccr |= (((rqc->brst_len - 1) & 0xf) << CC_SRCBRSTLEN_SHFT); ++ ccr |= (((rqc->brst_len - 1) & 0xf) << CC_DSTBRSTLEN_SHFT); ++ } ++ ++ ccr |= (rqc->brst_size << CC_SRCBRSTSIZE_SHFT); ++ ccr |= (rqc->brst_size << CC_DSTBRSTSIZE_SHFT); ++ ++ ccr |= (rqc->scctl << CC_SRCCCTRL_SHFT); ++ ccr |= (rqc->dcctl << CC_DSTCCTRL_SHFT); ++ ++ ccr |= (rqc->swap << CC_SWAP_SHFT); ++ ++ return ccr; ++} ++ ++ ++static inline int _setup_xfer(unsigned dry_run, u8 buf[], ++ const struct _xfer_spec *pxs) ++{ ++ u32 bytes = pxs->desc->px.bytes; ++ u32 bursts = BYTE_TO_BURST(bytes, pxs->ccr); ++ u32 singles = (bytes - BURST_TO_BYTE(bursts, pxs->ccr)) >> 2; ++ u32 ccr = pxs->ccr; ++ u32 src_addr = pxs->desc->px.src_addr; ++ u32 dst_addr = pxs->desc->px.dst_addr; ++ unsigned long c; ++ int off = 0; ++ ++ if ((pxs->desc->rqtype == DMA_DEV_TO_MEM) || ++ (pxs->desc->rqtype == DMA_MEM_TO_DEV)) { ++ if(bursts) { ++ off += _emit_MOV(dry_run, &buf[off], CCR, ccr); ++ off += _emit_MOV(dry_run, &buf[off], SAR, src_addr); ++ off += _emit_MOV(dry_run, &buf[off], DAR, dst_addr); ++ ++ off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri); ++ ++ while(bursts) { ++ c = (bursts > 256) ? 256 : bursts; ++ off += _req_loop(dry_run, &buf[off], BURST, &c, pxs); ++ bursts -= c; ++ } ++ } ++ ++ if (singles) { ++ ccr = _prepare_ccr(&pxs->desc->rqcfg, SINGLE); ++ if (pxs->desc->rqtype == DMA_MEM_TO_DEV) { ++ src_addr += bytes - singles * 4; ++ } else { ++ dst_addr += bytes - singles * 4; ++ } ++ off += _emit_MOV(dry_run, &buf[off], CCR, ccr); ++ off += _emit_MOV(dry_run, &buf[off], SAR, src_addr); ++ off += _emit_MOV(dry_run, &buf[off], DAR, dst_addr); ++ ++ while(singles) { ++ c = (singles > 256) ? 256 : singles; ++ off += _req_loop(dry_run, &buf[off], SINGLE, &c, pxs); ++ singles -= c; ++ } ++ ++ off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri); ++ } ++ } else { ++ /* Error if xfer length is not aligned at burst size */ ++ if (bytes % (BRST_SIZE(pxs->ccr) * BRST_LEN(pxs->ccr))) ++ return -EINVAL; ++ ++ off += _emit_MOV(dry_run, &buf[off], CCR, pxs->ccr); ++ off += _emit_MOV(dry_run, &buf[off], SAR, src_addr); ++ off += _emit_MOV(dry_run, &buf[off], DAR, dst_addr); ++ ++ while (bursts) { ++ c = bursts; ++ off += _loop(dry_run, &buf[off], &c, pxs); ++ bursts -= c; ++ } ++ } ++ ++ return off; ++} ++ ++/* ++ * A req is a sequence of one or more xfer units. ++ * Returns the number of bytes taken to setup the MC for the req. ++ */ ++static int _setup_req(unsigned dry_run, struct dma330_thread *thrd, ++ unsigned index, struct _xfer_spec *pxs) ++{ ++ struct _dma330_req *req = &thrd->req[index]; ++ u8 *buf = req->mc_cpu; ++ int off = 0; ++ ++ DMA330_DBGMC_START(req->mc_bus); ++ ++ off += _setup_xfer(dry_run, &buf[off], pxs); ++ ++ /* DMASEV peripheral/event */ ++ off += _emit_SEV(dry_run, &buf[off], thrd->ev); ++ /* DMAEND */ ++ off += _emit_END(dry_run, &buf[off]); ++ ++ return off; ++} ++ ++/* ++ * Submit a list of xfers after which the client wants notification. ++ * Client is not notified after each xfer unit, just once after all ++ * xfer units are done or some error occurs. ++ */ ++static int dma330_submit_req(struct dma330_thread *thrd, ++ struct dma_dma330_desc *desc) ++{ ++ struct dma330_dmac *dma330 = thrd->dmac; ++ struct _xfer_spec xs; ++ unsigned long flags; ++ unsigned idx; ++ u32 ccr; ++ int ret = 0; ++ ++ if (dma330->state == DYING ++ || dma330->dmac_tbd.reset_chan & (1 << thrd->id)) { ++ dev_info(thrd->dmac->ddma.dev, "%s:%d\n", ++ __func__, __LINE__); ++ return -EAGAIN; ++ } ++ ++ /* If request for non-existing peripheral */ ++ if (desc->rqtype != DMA_MEM_TO_MEM && ++ desc->peri >= dma330->pcfg.num_peri) { ++ dev_info(thrd->dmac->ddma.dev, ++ "%s:%d Invalid peripheral(%u)!\n", ++ __func__, __LINE__, desc->peri); ++ return -EINVAL; ++ } ++ ++ spin_lock_irqsave(&dma330->lock, flags); ++ ++ if (_queue_full(thrd)) { ++ ret = -EAGAIN; ++ goto xfer_exit; ++ } ++ ++ /* Prefer Secure Channel */ ++ if (!_manager_ns(thrd)) ++ desc->rqcfg.nonsecure = 0; ++ else ++ desc->rqcfg.nonsecure = 1; ++ ++ ccr = _prepare_ccr(&desc->rqcfg, BURST); ++ ++ idx = thrd->req[0].desc == NULL ? 0 : 1; ++ ++ xs.ccr = ccr; ++ xs.desc = desc; ++ ++ /* First dry run to check if req is acceptable */ ++ ret = _setup_req(1, thrd, idx, &xs); ++ if (ret < 0) ++ goto xfer_exit; ++ ++ if (ret > dma330->mcbufsz / 2) { ++ dev_info(dma330->ddma.dev, "%s:%d Try increasing mcbufsz (%i/%i)\n", ++ __func__, __LINE__, ret, dma330->mcbufsz / 2); ++ ret = -ENOMEM; ++ goto xfer_exit; ++ } ++ ++ /* Hook the request */ ++ thrd->lstenq = idx; ++ thrd->req[idx].desc = desc; ++ _setup_req(0, thrd, idx, &xs); ++ ++ ret = 0; ++ ++xfer_exit: ++ spin_unlock_irqrestore(&dma330->lock, flags); ++ ++ return ret; ++} ++ ++static void dma_dma330_rqcb(struct dma_dma330_desc *desc, enum dma330_op_err err) ++{ ++ struct dma_dma330_chan *pch; ++ unsigned long flags; ++ ++ if (!desc) ++ return; ++ ++ pch = desc->pchan; ++ ++ /* If desc aborted */ ++ if (!pch) ++ return; ++ ++ spin_lock_irqsave(&pch->lock, flags); ++ ++ desc->status = DONE; ++ ++ spin_unlock_irqrestore(&pch->lock, flags); ++ ++ tasklet_schedule(&pch->task); ++} ++ ++static void dma330_dotask(unsigned long data) ++{ ++ struct dma330_dmac *dma330 = (struct dma330_dmac *) data; ++ unsigned long flags; ++ int i; ++ ++ spin_lock_irqsave(&dma330->lock, flags); ++ ++ /* The DMAC itself gone nuts */ ++ if (dma330->dmac_tbd.reset_dmac) { ++ dma330->state = DYING; ++ /* Reset the manager too */ ++ dma330->dmac_tbd.reset_mngr = true; ++ /* Clear the reset flag */ ++ dma330->dmac_tbd.reset_dmac = false; ++ } ++ ++ if (dma330->dmac_tbd.reset_mngr) { ++ _stop(dma330->manager); ++ /* Reset all channels */ ++ dma330->dmac_tbd.reset_chan = (1 << dma330->pcfg.num_chan) - 1; ++ /* Clear the reset flag */ ++ dma330->dmac_tbd.reset_mngr = false; ++ } ++ ++ for (i = 0; i < dma330->pcfg.num_chan; i++) { ++ ++ if (dma330->dmac_tbd.reset_chan & (1 << i)) { ++ struct dma330_thread *thrd = &dma330->channels[i]; ++ void __iomem *regs = dma330->base; ++ enum dma330_op_err err; ++ ++ _stop(thrd); ++ ++ if (readl(regs + FSC) & (1 << thrd->id)) ++ err = DMA330_ERR_FAIL; ++ else ++ err = DMA330_ERR_ABORT; ++ ++ spin_unlock_irqrestore(&dma330->lock, flags); ++ dma_dma330_rqcb(thrd->req[1 - thrd->lstenq].desc, err); ++ dma_dma330_rqcb(thrd->req[thrd->lstenq].desc, err); ++ spin_lock_irqsave(&dma330->lock, flags); ++ ++ thrd->req[0].desc = NULL; ++ thrd->req[1].desc = NULL; ++ thrd->req_running = -1; ++ ++ /* Clear the reset flag */ ++ dma330->dmac_tbd.reset_chan &= ~(1 << i); ++ } ++ } ++ ++ spin_unlock_irqrestore(&dma330->lock, flags); ++ ++ return; ++} ++ ++/* Returns 1 if state was updated, 0 otherwise */ ++static int dma330_update(struct dma330_dmac *dma330) ++{ ++ struct dma_dma330_desc *descdone, *tmp; ++ unsigned long flags; ++ void __iomem *regs; ++ u32 val; ++ int id, ev, ret = 0; ++ ++ regs = dma330->base; ++ ++ spin_lock_irqsave(&dma330->lock, flags); ++ ++ val = readl(regs + FSM) & 0x1; ++ if (val) ++ dma330->dmac_tbd.reset_mngr = true; ++ else ++ dma330->dmac_tbd.reset_mngr = false; ++ ++ val = readl(regs + FSC) & ((1 << dma330->pcfg.num_chan) - 1); ++ dma330->dmac_tbd.reset_chan |= val; ++ if (val) { ++ int i = 0; ++ while (i < dma330->pcfg.num_chan) { ++ if (val & (1 << i)) { ++ dev_info(dma330->ddma.dev, ++ "Reset Channel-%d\t CS-%x FTC-%x\n", ++ i, readl(regs + CS(i)), ++ readl(regs + FTC(i))); ++ _stop(&dma330->channels[i]); ++ } ++ i++; ++ } ++ } ++ ++ /* Check which event happened i.e, thread notified */ ++ val = readl(regs + ES); ++ if (dma330->pcfg.num_events < 32 ++ && val & ~((1 << dma330->pcfg.num_events) - 1)) { ++ dma330->dmac_tbd.reset_dmac = true; ++ dev_err(dma330->ddma.dev, "%s:%d Unexpected!\n", __func__, ++ __LINE__); ++ ret = 1; ++ goto updt_exit; ++ } ++ ++ for (ev = 0; ev < dma330->pcfg.num_events; ev++) { ++ if (val & (1 << ev)) { /* Event occurred */ ++ struct dma330_thread *thrd; ++ u32 inten = readl(regs + INTEN); ++ int active; ++ ++ /* Clear the event */ ++ if (inten & (1 << ev)) ++ writel(1 << ev, regs + INTCLR); ++ ++ ret = 1; ++ ++ id = dma330->events[ev]; ++ ++ thrd = &dma330->channels[id]; ++ ++ active = thrd->req_running; ++ if (active == -1) /* Aborted */ ++ continue; ++ ++ /* Detach the req */ ++ descdone = thrd->req[active].desc; ++ thrd->req[active].desc = NULL; ++ ++ thrd->req_running = -1; ++ ++ /* Get going again ASAP */ ++ _start(thrd); ++ ++ /* For now, just make a list of callbacks to be done */ ++ list_add_tail(&descdone->rqd, &dma330->req_done); ++ } ++ } ++ ++ /* Now that we are in no hurry, do the callbacks */ ++ list_for_each_entry_safe(descdone, tmp, &dma330->req_done, rqd) { ++ list_del(&descdone->rqd); ++ spin_unlock_irqrestore(&dma330->lock, flags); ++ dma_dma330_rqcb(descdone, DMA330_ERR_NONE); ++ spin_lock_irqsave(&dma330->lock, flags); ++ } ++ ++updt_exit: ++ spin_unlock_irqrestore(&dma330->lock, flags); ++ ++ if (dma330->dmac_tbd.reset_dmac ++ || dma330->dmac_tbd.reset_mngr ++ || dma330->dmac_tbd.reset_chan) { ++ ret = 1; ++ tasklet_schedule(&dma330->tasks); ++ } ++ ++ return ret; ++} ++ ++/* Reserve an event */ ++static inline int _alloc_event(struct dma330_thread *thrd) ++{ ++ struct dma330_dmac *dma330 = thrd->dmac; ++ int ev; ++ ++ for (ev = 0; ev < dma330->pcfg.num_events; ev++) ++ if (dma330->events[ev] == -1) { ++ dma330->events[ev] = thrd->id; ++ return ev; ++ } ++ ++ return -1; ++} ++ ++static bool _chan_ns(const struct dma330_dmac *dma330, int i) ++{ ++ return dma330->pcfg.irq_ns & (1 << i); ++} ++ ++/* Upon success, returns IdentityToken for the ++ * allocated channel, NULL otherwise. ++ */ ++static struct dma330_thread *dma330_request_channel(struct dma330_dmac *dma330) ++{ ++ struct dma330_thread *thrd = NULL; ++ unsigned long flags; ++ int chans, i; ++ ++ if (dma330->state == DYING) ++ return NULL; ++ ++ chans = dma330->pcfg.num_chan; ++ ++ spin_lock_irqsave(&dma330->lock, flags); ++ ++ for (i = 0; i < chans; i++) { ++ thrd = &dma330->channels[i]; ++ if ((thrd->free) && (!_manager_ns(thrd) || ++ _chan_ns(dma330, i))) { ++ thrd->ev = _alloc_event(thrd); ++ if (thrd->ev >= 0) { ++ thrd->free = false; ++ thrd->lstenq = 1; ++ thrd->req[0].desc = NULL; ++ thrd->req[1].desc = NULL; ++ thrd->req_running = -1; ++ break; ++ } ++ } ++ thrd = NULL; ++ } ++ ++ spin_unlock_irqrestore(&dma330->lock, flags); ++ ++ return thrd; ++} ++ ++/* Release an event */ ++static inline void _free_event(struct dma330_thread *thrd, int ev) ++{ ++ struct dma330_dmac *dma330 = thrd->dmac; ++ ++ /* If the event is valid and was held by the thread */ ++ if (ev >= 0 && ev < dma330->pcfg.num_events ++ && dma330->events[ev] == thrd->id) ++ dma330->events[ev] = -1; ++} ++ ++static void dma330_release_channel(struct dma330_thread *thrd) ++{ ++ struct dma330_dmac *dma330; ++ unsigned long flags; ++ ++ if (!thrd || thrd->free) ++ return; ++ ++ _stop(thrd); ++ ++ dma_dma330_rqcb(thrd->req[1 - thrd->lstenq].desc, DMA330_ERR_ABORT); ++ dma_dma330_rqcb(thrd->req[thrd->lstenq].desc, DMA330_ERR_ABORT); ++ ++ dma330 = thrd->dmac; ++ ++ spin_lock_irqsave(&dma330->lock, flags); ++ _free_event(thrd, thrd->ev); ++ thrd->free = true; ++ spin_unlock_irqrestore(&dma330->lock, flags); ++} ++ ++/* Initialize the structure for DMA330 configuration, that can be used ++ * by the client driver the make best use of the DMAC ++ */ ++static void read_dmac_config(struct dma330_dmac *dma330) ++{ ++ void __iomem *regs = dma330->base; ++ u32 val; ++ ++ val = readl(regs + CRD) >> CRD_DATA_WIDTH_SHIFT; ++ val &= CRD_DATA_WIDTH_MASK; ++ dma330->pcfg.data_bus_width = 8 * (1 << val); ++ ++ val = readl(regs + CRD) >> CRD_DATA_BUFF_SHIFT; ++ val &= CRD_DATA_BUFF_MASK; ++ dma330->pcfg.data_buf_dep = val + 1; ++ ++ val = readl(regs + CR0) >> CR0_NUM_CHANS_SHIFT; ++ val &= CR0_NUM_CHANS_MASK; ++ val += 1; ++ dma330->pcfg.num_chan = val; ++ ++ val = readl(regs + CR0); ++ if (val & CR0_PERIPH_REQ_SET) { ++ val = (val >> CR0_NUM_PERIPH_SHIFT) & CR0_NUM_PERIPH_MASK; ++ val += 1; ++ dma330->pcfg.num_peri = val; ++ dma330->pcfg.peri_ns = readl(regs + CR4); ++ } else { ++ dma330->pcfg.num_peri = 0; ++ } ++ ++ val = readl(regs + CR0); ++ if (val & CR0_BOOT_MAN_NS) ++ dma330->pcfg.mode |= DMAC_MODE_NS; ++ else ++ dma330->pcfg.mode &= ~DMAC_MODE_NS; ++ ++ val = readl(regs + CR0) >> CR0_NUM_EVENTS_SHIFT; ++ val &= CR0_NUM_EVENTS_MASK; ++ val += 1; ++ dma330->pcfg.num_events = val; ++ ++ dma330->pcfg.irq_ns = readl(regs + CR3); ++} ++ ++static inline void _reset_thread(struct dma330_thread *thrd) ++{ ++ struct dma330_dmac *dma330 = thrd->dmac; ++ ++ thrd->req[0].mc_cpu = dma330->mcode_cpu ++ + (thrd->id * dma330->mcbufsz); ++ thrd->req[0].mc_bus = dma330->mcode_bus ++ + (thrd->id * dma330->mcbufsz); ++ thrd->req[0].desc = NULL; ++ ++ thrd->req[1].mc_cpu = thrd->req[0].mc_cpu ++ + dma330->mcbufsz / 2; ++ thrd->req[1].mc_bus = thrd->req[0].mc_bus ++ + dma330->mcbufsz / 2; ++ thrd->req[1].desc = NULL; ++ ++ thrd->req_running = -1; ++} ++ ++static int dmac_alloc_threads(struct dma330_dmac *dma330) ++{ ++ int chans = dma330->pcfg.num_chan; ++ struct dma330_thread *thrd; ++ int i; ++ ++ /* Allocate 1 Manager and 'chans' Channel threads */ ++ dma330->channels = kzalloc((1 + chans) * sizeof(*thrd), ++ GFP_KERNEL); ++ if (!dma330->channels) ++ return -ENOMEM; ++ ++ /* Init Channel threads */ ++ for (i = 0; i < chans; i++) { ++ thrd = &dma330->channels[i]; ++ thrd->id = i; ++ thrd->dmac = dma330; ++ _reset_thread(thrd); ++ thrd->free = true; ++ } ++ ++ /* MANAGER is indexed at the end */ ++ thrd = &dma330->channels[chans]; ++ thrd->id = chans; ++ thrd->dmac = dma330; ++ thrd->free = false; ++ dma330->manager = thrd; ++ ++ return 0; ++} ++ ++static int dmac_alloc_resources(struct dma330_dmac *dma330) ++{ ++ int chans = dma330->pcfg.num_chan; ++ int ret; ++ ++ /* ++ * Alloc MicroCode buffer for 'chans' Channel threads. ++ * A channel's buffer offset is (Channel_Id * MCODE_BUFF_PERCHAN) ++ */ ++ dma330->mcode_cpu = dma_alloc_coherent(dma330->ddma.dev, ++ chans * dma330->mcbufsz, ++ &dma330->mcode_bus, GFP_KERNEL); ++ if (!dma330->mcode_cpu) { ++ dev_err(dma330->ddma.dev, "%s:%d Can't allocate memory!\n", ++ __func__, __LINE__); ++ return -ENOMEM; ++ } ++ ++ ret = dmac_alloc_threads(dma330); ++ if (ret) { ++ dev_err(dma330->ddma.dev, "%s:%d Can't to create channels for DMAC!\n", ++ __func__, __LINE__); ++ dma_free_coherent(dma330->ddma.dev, ++ chans * dma330->mcbufsz, ++ dma330->mcode_cpu, dma330->mcode_bus); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int dma330_add(struct dma330_dmac *dma330) ++{ ++ void __iomem *regs; ++ int i, ret; ++ ++ regs = dma330->base; ++ ++ /* Check if we can handle this DMAC */ ++ if ((dma330->pcfg.periph_id & 0xffffff) != PERIPH_ID_VAL) { ++ dev_err(dma330->ddma.dev, "PERIPH_ID 0x%x !\n", ++ dma330->pcfg.periph_id); ++ return -EINVAL; ++ } ++ ++ /* Read the configuration of the DMAC */ ++ read_dmac_config(dma330); ++ ++ if (dma330->pcfg.num_events == 0) { ++ dev_err(dma330->ddma.dev, "%s:%d Can't work without events!\n", ++ __func__, __LINE__); ++ return -EINVAL; ++ } ++ ++ spin_lock_init(&dma330->lock); ++ ++ INIT_LIST_HEAD(&dma330->req_done); ++ ++ /* Use default MC buffer size if not provided */ ++ if (!dma330->mcbufsz) ++ dma330->mcbufsz = MCODE_BUFF_PER_REQ * 2; ++ ++ /* Mark all events as free */ ++ for (i = 0; i < dma330->pcfg.num_events; i++) ++ dma330->events[i] = -1; ++ ++ /* Allocate resources needed by the DMAC */ ++ ret = dmac_alloc_resources(dma330); ++ if (ret) { ++ dev_err(dma330->ddma.dev, "Unable to create channels for DMAC\n"); ++ return ret; ++ } ++ ++ tasklet_init(&dma330->tasks, dma330_dotask, (unsigned long) dma330); ++ ++ dma330->state = INIT; ++ ++ return 0; ++} ++ ++static int dmac_free_threads(struct dma330_dmac *dma330) ++{ ++ struct dma330_thread *thrd; ++ int i; ++ ++ /* Release Channel threads */ ++ for (i = 0; i < dma330->pcfg.num_chan; i++) { ++ thrd = &dma330->channels[i]; ++ dma330_release_channel(thrd); ++ } ++ ++ /* Free memory */ ++ kfree(dma330->channels); ++ ++ return 0; ++} ++ ++static void dma330_del(struct dma330_dmac *dma330) ++{ ++ dma330->state = UNINIT; ++ ++ tasklet_kill(&dma330->tasks); ++ ++ /* Free DMAC resources */ ++ dmac_free_threads(dma330); ++ ++ dma_free_coherent(dma330->ddma.dev, ++ dma330->pcfg.num_chan * dma330->mcbufsz, dma330->mcode_cpu, ++ dma330->mcode_bus); ++} ++ ++/* forward declaration */ ++static struct amba_driver iproc_dma330_driver; ++ ++static inline struct dma_dma330_chan * ++to_pchan(struct dma_chan *ch) ++{ ++ if (!ch) ++ return NULL; ++ ++ return container_of(ch, struct dma_dma330_chan, chan); ++} ++ ++static inline struct dma_dma330_desc * ++to_desc(struct dma_async_tx_descriptor *tx) ++{ ++ return container_of(tx, struct dma_dma330_desc, txd); ++} ++ ++static inline void fill_queue(struct dma_dma330_chan *pch) ++{ ++ struct dma_dma330_desc *desc; ++ int ret; ++ ++ list_for_each_entry(desc, &pch->work_list, node) { ++ ++ /* If already submitted */ ++ if (desc->status == BUSY) ++ continue; ++ ++ ret = dma330_submit_req(pch->thread, desc); ++ if (!ret) { ++ desc->status = BUSY; ++ } else if (ret == -EAGAIN) { ++ /* QFull or DMAC Dying */ ++ break; ++ } else { ++ /* Unacceptable request */ ++ desc->status = DONE; ++ dev_err(pch->dmac->ddma.dev, "%s:%d Bad Desc(%d)\n", ++ __func__, __LINE__, desc->txd.cookie); ++ tasklet_schedule(&pch->task); ++ } ++ } ++} ++ ++static void dma330_tasklet(unsigned long data) ++{ ++ struct dma_dma330_chan *pch = (struct dma_dma330_chan *)data; ++ struct dma_dma330_desc *desc, *_dt; ++ unsigned long flags; ++ bool power_down = false; ++ ++ spin_lock_irqsave(&pch->lock, flags); ++ ++ /* Pick up ripe tomatoes */ ++ list_for_each_entry_safe(desc, _dt, &pch->work_list, node) ++ if (desc->status == DONE) { ++ if (!pch->cyclic) ++ dma_cookie_complete(&desc->txd); ++ list_move_tail(&desc->node, &pch->completed_list); ++ } ++ ++ /* Try to submit a req imm. next to the last completed cookie */ ++ fill_queue(pch); ++ ++ if (list_empty(&pch->work_list)) { ++ spin_lock(&pch->thread->dmac->lock); ++ _stop(pch->thread); ++ spin_unlock(&pch->thread->dmac->lock); ++ power_down = true; ++ } else { ++ /* Make sure the DMA330 Channel thread is active */ ++ spin_lock(&pch->thread->dmac->lock); ++ _start(pch->thread); ++ spin_unlock(&pch->thread->dmac->lock); ++ } ++ ++ while (!list_empty(&pch->completed_list)) { ++ dma_async_tx_callback callback; ++ void *callback_param; ++ ++ desc = list_first_entry(&pch->completed_list, ++ struct dma_dma330_desc, node); ++ ++ callback = desc->txd.callback; ++ callback_param = desc->txd.callback_param; ++ ++ if (pch->cyclic) { ++ desc->status = PREP; ++ list_move_tail(&desc->node, &pch->work_list); ++ if (power_down) { ++ spin_lock(&pch->thread->dmac->lock); ++ _start(pch->thread); ++ spin_unlock(&pch->thread->dmac->lock); ++ power_down = false; ++ } ++ } else { ++ desc->status = FREE; ++ list_move_tail(&desc->node, &pch->dmac->desc_pool); ++ } ++ ++ dma_descriptor_unmap(&desc->txd); ++ ++ if (callback) { ++ spin_unlock_irqrestore(&pch->lock, flags); ++ callback(callback_param); ++ spin_lock_irqsave(&pch->lock, flags); ++ } ++ } ++ spin_unlock_irqrestore(&pch->lock, flags); ++ ++ /* If work list empty, power down */ ++ if (power_down) { ++ pm_runtime_mark_last_busy(pch->dmac->ddma.dev); ++ pm_runtime_put_autosuspend(pch->dmac->ddma.dev); ++ } ++} ++ ++bool dma330_filter(struct dma_chan *chan, void *param) ++{ ++ u8 *peri_id; ++ ++ if (chan->device->dev->driver != &iproc_dma330_driver.drv) ++ return false; ++ ++ peri_id = chan->private; ++ return *peri_id == (unsigned long)param; ++} ++EXPORT_SYMBOL(dma330_filter); ++ ++static struct dma_chan *of_dma_dma330_xlate(struct of_phandle_args *dma_spec, ++ struct of_dma *ofdma) ++{ ++ int count = dma_spec->args_count; ++ struct dma330_dmac *dma330 = ofdma->of_dma_data; ++ unsigned int chan_id; ++ ++ if (!dma330) ++ return NULL; ++ ++ if (count != 1) ++ return NULL; ++ ++ chan_id = dma_spec->args[0]; ++ if (chan_id >= dma330->num_peripherals) ++ return NULL; ++ ++ return dma_get_slave_channel(&dma330->peripherals[chan_id].chan); ++} ++ ++static int dma330_alloc_chan_resources(struct dma_chan *chan) ++{ ++ struct dma_dma330_chan *pch = to_pchan(chan); ++ struct dma330_dmac *dma330 = pch->dmac; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&pch->lock, flags); ++ ++ dma_cookie_init(chan); ++ pch->cyclic = false; ++ ++ pch->thread = dma330_request_channel(dma330); ++ if (!pch->thread) { ++ spin_unlock_irqrestore(&pch->lock, flags); ++ return -ENOMEM; ++ } ++ ++ tasklet_init(&pch->task, dma330_tasklet, (unsigned long) pch); ++ ++ spin_unlock_irqrestore(&pch->lock, flags); ++ ++ return 1; ++} ++ ++static int dma330_config(struct dma_chan *chan, ++ struct dma_slave_config *slave_config) ++{ ++ struct dma_dma330_chan *pch = to_pchan(chan); ++ ++ if (slave_config->direction == DMA_MEM_TO_DEV) { ++ if (slave_config->dst_addr) ++ pch->fifo_addr = slave_config->dst_addr; ++ if (slave_config->dst_addr_width) ++ pch->burst_sz = __ffs(slave_config->dst_addr_width); ++ if (slave_config->dst_maxburst) ++ pch->burst_len = slave_config->dst_maxburst; ++ } else if (slave_config->direction == DMA_DEV_TO_MEM) { ++ if (slave_config->src_addr) ++ pch->fifo_addr = slave_config->src_addr; ++ if (slave_config->src_addr_width) ++ pch->burst_sz = __ffs(slave_config->src_addr_width); ++ if (slave_config->src_maxburst) ++ pch->burst_len = slave_config->src_maxburst; ++ } ++ ++ return 0; ++} ++ ++static int dma330_terminate_all(struct dma_chan *chan) ++{ ++ struct dma_dma330_chan *pch = to_pchan(chan); ++ struct dma_dma330_desc *desc; ++ unsigned long flags; ++ struct dma330_dmac *dma330 = pch->dmac; ++ LIST_HEAD(list); ++ ++ pm_runtime_get_sync(dma330->ddma.dev); ++ spin_lock_irqsave(&pch->lock, flags); ++ spin_lock(&dma330->lock); ++ _stop(pch->thread); ++ spin_unlock(&dma330->lock); ++ ++ pch->thread->req[0].desc = NULL; ++ pch->thread->req[1].desc = NULL; ++ pch->thread->req_running = -1; ++ ++ /* Mark all desc done */ ++ list_for_each_entry(desc, &pch->submitted_list, node) { ++ desc->status = FREE; ++ dma_cookie_complete(&desc->txd); ++ } ++ ++ list_for_each_entry(desc, &pch->work_list , node) { ++ desc->status = FREE; ++ dma_cookie_complete(&desc->txd); ++ } ++ ++ list_splice_tail_init(&pch->submitted_list, &dma330->desc_pool); ++ list_splice_tail_init(&pch->work_list, &dma330->desc_pool); ++ list_splice_tail_init(&pch->completed_list, &dma330->desc_pool); ++ spin_unlock_irqrestore(&pch->lock, flags); ++ pm_runtime_mark_last_busy(dma330->ddma.dev); ++ pm_runtime_put_autosuspend(dma330->ddma.dev); ++ ++ return 0; ++} ++ ++/* ++ * We don't support DMA_RESUME command because of hardware ++ * limitations, so after pausing the channel we cannot restore ++ * it to active state. We have to terminate channel and setup ++ * DMA transfer again. This pause feature was implemented to ++ * allow safely read residue before channel termination. ++ */ ++static int dma330_pause(struct dma_chan *chan) ++{ ++ struct dma_dma330_chan *pch = to_pchan(chan); ++ struct dma330_dmac *dma330 = pch->dmac; ++ unsigned long flags; ++ ++ pm_runtime_get_sync(dma330->ddma.dev); ++ spin_lock_irqsave(&pch->lock, flags); ++ ++ spin_lock(&dma330->lock); ++ _stop(pch->thread); ++ spin_unlock(&dma330->lock); ++ ++ spin_unlock_irqrestore(&pch->lock, flags); ++ pm_runtime_mark_last_busy(dma330->ddma.dev); ++ pm_runtime_put_autosuspend(dma330->ddma.dev); ++ ++ return 0; ++} ++ ++static void dma330_free_chan_resources(struct dma_chan *chan) ++{ ++ struct dma_dma330_chan *pch = to_pchan(chan); ++ unsigned long flags; ++ ++ tasklet_kill(&pch->task); ++ ++ pm_runtime_get_sync(pch->dmac->ddma.dev); ++ spin_lock_irqsave(&pch->lock, flags); ++ ++ dma330_release_channel(pch->thread); ++ pch->thread = NULL; ++ ++ if (pch->cyclic) ++ list_splice_tail_init(&pch->work_list, &pch->dmac->desc_pool); ++ ++ spin_unlock_irqrestore(&pch->lock, flags); ++ pm_runtime_mark_last_busy(pch->dmac->ddma.dev); ++ pm_runtime_put_autosuspend(pch->dmac->ddma.dev); ++} ++ ++static int dma330_get_current_xferred_count(struct dma_dma330_chan *pch, ++ struct dma_dma330_desc *desc) ++{ ++ struct dma330_thread *thrd = pch->thread; ++ struct dma330_dmac *dma330 = pch->dmac; ++ void __iomem *regs = thrd->dmac->base; ++ u32 val, addr; ++ ++ pm_runtime_get_sync(dma330->ddma.dev); ++ val = addr = 0; ++ if (desc->rqcfg.src_inc) { ++ val = readl(regs + SA(thrd->id)); ++ addr = desc->px.src_addr; ++ } else { ++ val = readl(regs + DA(thrd->id)); ++ addr = desc->px.dst_addr; ++ } ++ pm_runtime_mark_last_busy(pch->dmac->ddma.dev); ++ pm_runtime_put_autosuspend(dma330->ddma.dev); ++ return val - addr; ++} ++ ++static enum dma_status ++dma330_tx_status(struct dma_chan *chan, dma_cookie_t cookie, ++ struct dma_tx_state *txstate) ++{ ++ enum dma_status ret; ++ unsigned long flags; ++ struct dma_dma330_desc *desc, *running = NULL; ++ struct dma_dma330_chan *pch = to_pchan(chan); ++ unsigned int transferred, residual = 0; ++ ++ ret = dma_cookie_status(chan, cookie, txstate); ++ ++ if (!txstate) ++ return ret; ++ ++ if (ret == DMA_COMPLETE) ++ goto out; ++ ++ spin_lock_irqsave(&pch->lock, flags); ++ ++ if (pch->thread->req_running != -1) ++ running = pch->thread->req[pch->thread->req_running].desc; ++ ++ /* Check in pending list */ ++ list_for_each_entry(desc, &pch->work_list, node) { ++ if (desc->status == DONE) ++ transferred = desc->bytes_requested; ++ else if (running && desc == running) ++ transferred = ++ dma330_get_current_xferred_count(pch, desc); ++ else ++ transferred = 0; ++ residual += desc->bytes_requested - transferred; ++ if (desc->txd.cookie == cookie) { ++ switch (desc->status) { ++ case DONE: ++ ret = DMA_COMPLETE; ++ break; ++ case PREP: ++ case BUSY: ++ ret = DMA_IN_PROGRESS; ++ break; ++ default: ++ WARN_ON(1); ++ } ++ break; ++ } ++ if (desc->last) ++ residual = 0; ++ } ++ spin_unlock_irqrestore(&pch->lock, flags); ++ ++out: ++ dma_set_residue(txstate, residual); ++ ++ return ret; ++} ++ ++static void dma330_issue_pending(struct dma_chan *chan) ++{ ++ struct dma_dma330_chan *pch = to_pchan(chan); ++ unsigned long flags; ++ ++ spin_lock_irqsave(&pch->lock, flags); ++ if (list_empty(&pch->work_list)) { ++ /* ++ * Warn on nothing pending. Empty submitted_list may ++ * break our pm_runtime usage counter as it is ++ * updated on work_list emptiness status. ++ */ ++ WARN_ON(list_empty(&pch->submitted_list)); ++ pm_runtime_get_sync(pch->dmac->ddma.dev); ++ } ++ list_splice_tail_init(&pch->submitted_list, &pch->work_list); ++ spin_unlock_irqrestore(&pch->lock, flags); ++ ++ dma330_tasklet((unsigned long)pch); ++} ++ ++/* ++ * We returned the last one of the circular list of descriptor(s) ++ * from prep_xxx, so the argument to submit corresponds to the last ++ * descriptor of the list. ++ */ ++static dma_cookie_t dma330_tx_submit(struct dma_async_tx_descriptor *tx) ++{ ++ struct dma_dma330_desc *desc, *last = to_desc(tx); ++ struct dma_dma330_chan *pch = to_pchan(tx->chan); ++ dma_cookie_t cookie; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&pch->lock, flags); ++ ++ /* Assign cookies to all nodes */ ++ while (!list_empty(&last->node)) { ++ desc = list_entry(last->node.next, struct dma_dma330_desc, node); ++ if (pch->cyclic) { ++ desc->txd.callback = last->txd.callback; ++ desc->txd.callback_param = last->txd.callback_param; ++ } ++ desc->last = false; ++ ++ dma_cookie_assign(&desc->txd); ++ ++ list_move_tail(&desc->node, &pch->submitted_list); ++ } ++ ++ last->last = true; ++ cookie = dma_cookie_assign(&last->txd); ++ list_add_tail(&last->node, &pch->submitted_list); ++ spin_unlock_irqrestore(&pch->lock, flags); ++ ++ return cookie; ++} ++ ++static inline void _init_desc(struct dma_dma330_desc *desc) ++{ ++#ifdef __LITTLE_ENDIAN ++ desc->rqcfg.swap = SWAP_NO; ++#else ++ desc->rqcfg.swap = SWAP_4; ++#endif /* __LITTLE_ENDIAN */ ++ desc->rqcfg.scctl = CCTRL0; ++ desc->rqcfg.dcctl = CCTRL0; ++ desc->txd.tx_submit = dma330_tx_submit; ++ ++ INIT_LIST_HEAD(&desc->node); ++} ++ ++/* Returns the number of descriptors added to the DMAC pool */ ++static int add_desc(struct dma330_dmac *dma330, gfp_t flg, int count) ++{ ++ struct dma_dma330_desc *desc; ++ unsigned long flags; ++ int i; ++ ++ desc = kcalloc(count, sizeof(*desc), flg); ++ if (!desc) ++ return 0; ++ ++ spin_lock_irqsave(&dma330->pool_lock, flags); ++ ++ for (i = 0; i < count; i++) { ++ _init_desc(&desc[i]); ++ list_add_tail(&desc[i].node, &dma330->desc_pool); ++ } ++ ++ spin_unlock_irqrestore(&dma330->pool_lock, flags); ++ ++ return count; ++} ++ ++static struct dma_dma330_desc *pluck_desc(struct dma330_dmac *dma330) ++{ ++ struct dma_dma330_desc *desc = NULL; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&dma330->pool_lock, flags); ++ ++ if (!list_empty(&dma330->desc_pool)) { ++ desc = list_entry(dma330->desc_pool.next, ++ struct dma_dma330_desc, node); ++ ++ list_del_init(&desc->node); ++ ++ desc->status = PREP; ++ desc->txd.callback = NULL; ++ } ++ ++ spin_unlock_irqrestore(&dma330->pool_lock, flags); ++ ++ return desc; ++} ++ ++static struct dma_dma330_desc *dma330_get_desc(struct dma_dma330_chan *pch) ++{ ++ struct dma330_dmac *dma330 = pch->dmac; ++ u8 *peri_id = pch->chan.private; ++ struct dma_dma330_desc *desc; ++ ++ /* Pluck one desc from the pool of DMAC */ ++ desc = pluck_desc(dma330); ++ ++ /* If the DMAC pool is empty, alloc new */ ++ if (!desc) { ++ if (!add_desc(dma330, GFP_ATOMIC, 1)) ++ return NULL; ++ ++ /* Try again */ ++ desc = pluck_desc(dma330); ++ if (!desc) { ++ dev_err(pch->dmac->ddma.dev, ++ "%s:%d ALERT!\n", __func__, __LINE__); ++ return NULL; ++ } ++ } ++ ++ /* Initialize the descriptor */ ++ desc->pchan = pch; ++ desc->txd.cookie = 0; ++ async_tx_ack(&desc->txd); ++ ++ desc->peri = peri_id ? pch->chan.chan_id : 0; ++ desc->rqcfg.pcfg = &pch->dmac->pcfg; ++ ++ dma_async_tx_descriptor_init(&desc->txd, &pch->chan); ++ ++ return desc; ++} ++ ++static inline void fill_px(struct dma330_xfer *px, ++ dma_addr_t dst, dma_addr_t src, size_t len) ++{ ++ px->bytes = len; ++ px->dst_addr = dst; ++ px->src_addr = src; ++} ++ ++static struct dma_dma330_desc * ++__dma330_prep_dma_memcpy(struct dma_dma330_chan *pch, dma_addr_t dst, ++ dma_addr_t src, size_t len) ++{ ++ struct dma_dma330_desc *desc = dma330_get_desc(pch); ++ ++ if (!desc) { ++ dev_err(pch->dmac->ddma.dev, "%s:%d Unable to fetch desc\n", ++ __func__, __LINE__); ++ return NULL; ++ } ++ ++ /* ++ * Ideally we should lookout for reqs bigger than ++ * those that can be programmed with 256 bytes of ++ * MC buffer, but considering a req size is seldom ++ * going to be word-unaligned and more than 200MB, ++ * we take it easy. ++ * Also, should the limit is reached we'd rather ++ * have the platform increase MC buffer size than ++ * complicating this API driver. ++ */ ++ fill_px(&desc->px, dst, src, len); ++ ++ return desc; ++} ++ ++/* Call after fixing burst size */ ++static inline int get_burst_len(struct dma_dma330_desc *desc, size_t len) ++{ ++ struct dma_dma330_chan *pch = desc->pchan; ++ struct dma330_dmac *dma330 = pch->dmac; ++ int burst_len; ++ ++ burst_len = dma330->pcfg.data_bus_width / 8; ++ burst_len *= dma330->pcfg.data_buf_dep / dma330->pcfg.num_chan; ++ burst_len >>= desc->rqcfg.brst_size; ++ ++ /* src/dst_burst_len can't be more than 16 */ ++ if (burst_len > 16) ++ burst_len = 16; ++ ++ while (burst_len > 1) { ++ if (!(len % (burst_len << desc->rqcfg.brst_size))) ++ break; ++ burst_len--; ++ } ++ ++ return burst_len; ++} ++ ++static struct dma_async_tx_descriptor *dma330_prep_dma_cyclic( ++ struct dma_chan *chan, dma_addr_t dma_addr, size_t len, ++ size_t period_len, enum dma_transfer_direction direction, ++ unsigned long flags) ++{ ++ struct dma_dma330_desc *desc = NULL, *first = NULL; ++ struct dma_dma330_chan *pch = to_pchan(chan); ++ struct dma330_dmac *dma330 = pch->dmac; ++ unsigned int i; ++ dma_addr_t dst; ++ dma_addr_t src; ++ ++ if (len % period_len != 0) ++ return NULL; ++ ++ if (!is_slave_direction(direction)) { ++ dev_err(pch->dmac->ddma.dev, "%s:%d Invalid dma direction\n", ++ __func__, __LINE__); ++ return NULL; ++ } ++ ++ for (i = 0; i < len / period_len; i++) { ++ desc = dma330_get_desc(pch); ++ if (!desc) { ++ dev_err(pch->dmac->ddma.dev, "%s:%d Unable to fetch desc\n", ++ __func__, __LINE__); ++ ++ if (!first) ++ return NULL; ++ ++ spin_lock_irqsave(&dma330->pool_lock, flags); ++ ++ while (!list_empty(&first->node)) { ++ desc = list_entry(first->node.next, ++ struct dma_dma330_desc, node); ++ list_move_tail(&desc->node, &dma330->desc_pool); ++ } ++ ++ list_move_tail(&first->node, &dma330->desc_pool); ++ ++ spin_unlock_irqrestore(&dma330->pool_lock, flags); ++ ++ return NULL; ++ } ++ ++ switch (direction) { ++ case DMA_MEM_TO_DEV: ++ desc->rqcfg.src_inc = 1; ++ desc->rqcfg.dst_inc = 0; ++ src = dma_addr; ++ dst = pch->fifo_addr; ++ break; ++ case DMA_DEV_TO_MEM: ++ desc->rqcfg.src_inc = 0; ++ desc->rqcfg.dst_inc = 1; ++ src = pch->fifo_addr; ++ dst = dma_addr; ++ break; ++ default: ++ break; ++ } ++ ++ desc->rqtype = direction; ++ desc->rqcfg.brst_size = pch->burst_sz; ++ desc->rqcfg.brst_len = pch->burst_len; ++ desc->bytes_requested = period_len; ++ fill_px(&desc->px, dst, src, period_len); ++ ++ if (!first) ++ first = desc; ++ else ++ list_add_tail(&desc->node, &first->node); ++ ++ dma_addr += period_len; ++ } ++ ++ if (!desc) ++ return NULL; ++ ++ pch->cyclic = true; ++ desc->txd.flags = flags; ++ ++ return &desc->txd; ++} ++ ++static struct dma_async_tx_descriptor * ++dma330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst, ++ dma_addr_t src, size_t len, unsigned long flags) ++{ ++ struct dma_dma330_desc *desc; ++ struct dma_dma330_chan *pch = to_pchan(chan); ++ struct dma330_dmac *dma330; ++ int burst; ++ ++ if (unlikely(!pch || !len)) ++ return NULL; ++ ++ dma330 = pch->dmac; ++ ++ desc = __dma330_prep_dma_memcpy(pch, dst, src, len); ++ if (!desc) ++ return NULL; ++ ++ desc->rqcfg.src_inc = 1; ++ desc->rqcfg.dst_inc = 1; ++ desc->rqtype = DMA_MEM_TO_MEM; ++ ++ /* Select max possible burst size */ ++ burst = dma330->pcfg.data_bus_width / 8; ++ ++ /* ++ * Make sure we use a burst size that aligns with all the memcpy ++ * parameters because our DMA programming algorithm doesn't cope with ++ * transfers which straddle an entry in the DMA device's MFIFO. ++ */ ++ while ((src | dst | len) & (burst - 1)) ++ burst /= 2; ++ ++ desc->rqcfg.brst_size = 0; ++ while (burst != (1 << desc->rqcfg.brst_size)) ++ desc->rqcfg.brst_size++; ++ ++ /* ++ * If burst size is smaller than bus width then make sure we only ++ * transfer one at a time to avoid a burst stradling an MFIFO entry. ++ */ ++ if (desc->rqcfg.brst_size * 8 < dma330->pcfg.data_bus_width) ++ desc->rqcfg.brst_len = 1; ++ ++ desc->rqcfg.brst_len = get_burst_len(desc, len); ++ desc->bytes_requested = len; ++ ++ desc->txd.flags = flags; ++ ++ return &desc->txd; ++} ++ ++static void __dma330_giveback_desc(struct dma330_dmac *dma330, ++ struct dma_dma330_desc *first) ++{ ++ unsigned long flags; ++ struct dma_dma330_desc *desc; ++ ++ if (!first) ++ return; ++ ++ spin_lock_irqsave(&dma330->pool_lock, flags); ++ ++ while (!list_empty(&first->node)) { ++ desc = list_entry(first->node.next, ++ struct dma_dma330_desc, node); ++ list_move_tail(&desc->node, &dma330->desc_pool); ++ } ++ ++ list_move_tail(&first->node, &dma330->desc_pool); ++ ++ spin_unlock_irqrestore(&dma330->pool_lock, flags); ++} ++ ++static struct dma_async_tx_descriptor * ++dma330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, ++ unsigned int sg_len, enum dma_transfer_direction direction, ++ unsigned long flg, void *context) ++{ ++ struct dma_dma330_desc *first, *desc = NULL; ++ struct dma_dma330_chan *pch = to_pchan(chan); ++ struct scatterlist *sg; ++ int i; ++ dma_addr_t addr; ++ ++ if (unlikely(!pch || !sgl || !sg_len)) ++ return NULL; ++ ++ addr = pch->fifo_addr; ++ ++ first = NULL; ++ ++ for_each_sg(sgl, sg, sg_len, i) { ++ ++ desc = dma330_get_desc(pch); ++ if (!desc) { ++ struct dma330_dmac *dma330 = pch->dmac; ++ ++ dev_err(pch->dmac->ddma.dev, ++ "%s:%d Unable to fetch desc\n", ++ __func__, __LINE__); ++ __dma330_giveback_desc(dma330, first); ++ ++ return NULL; ++ } ++ ++ if (!first) ++ first = desc; ++ else ++ list_add_tail(&desc->node, &first->node); ++ ++ if (direction == DMA_MEM_TO_DEV) { ++ desc->rqcfg.src_inc = 1; ++ desc->rqcfg.dst_inc = 0; ++ fill_px(&desc->px, ++ addr, sg_dma_address(sg), sg_dma_len(sg)); ++ } else { ++ desc->rqcfg.src_inc = 0; ++ desc->rqcfg.dst_inc = 1; ++ fill_px(&desc->px, ++ sg_dma_address(sg), addr, sg_dma_len(sg)); ++ } ++ ++ desc->rqcfg.brst_size = pch->burst_sz; ++ desc->rqcfg.brst_len = pch->burst_len; ++ desc->rqtype = direction; ++ desc->bytes_requested = sg_dma_len(sg); ++ } ++ ++ /* Return the last desc in the chain */ ++ desc->txd.flags = flg; ++ return &desc->txd; ++} ++ ++static irqreturn_t dma330_irq_handler(int irq, void *data) ++{ ++ if (dma330_update(data)) ++ return IRQ_HANDLED; ++ else ++ return IRQ_NONE; ++} ++ ++#define DMA330_DMA_BUSWIDTHS \ ++ BIT(DMA_SLAVE_BUSWIDTH_UNDEFINED) | \ ++ BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \ ++ BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \ ++ BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | \ ++ BIT(DMA_SLAVE_BUSWIDTH_8_BYTES) ++ ++/* ++ * Runtime PM callbacks are provided by amba/bus.c driver. ++ * ++ * It is assumed here that IRQ safe runtime PM is chosen in probe and amba ++ * bus driver will only disable/enable the clock in runtime PM callbacks. ++ */ ++static int __maybe_unused iproc_dma330_suspend(struct device *dev) ++{ ++ struct amba_device *pcdev = to_amba_device(dev); ++ ++ pm_runtime_disable(dev); ++ ++ if (!pm_runtime_status_suspended(dev)) { ++ /* amba did not disable the clock */ ++ amba_pclk_disable(pcdev); ++ } ++ amba_pclk_unprepare(pcdev); ++ ++ return 0; ++} ++ ++static int __maybe_unused iproc_dma330_resume(struct device *dev) ++{ ++ struct amba_device *pcdev = to_amba_device(dev); ++ int ret; ++ ++ ret = amba_pclk_prepare(pcdev); ++ if (ret) ++ return ret; ++ ++ if (!pm_runtime_status_suspended(dev)) ++ ret = amba_pclk_enable(pcdev); ++ ++ pm_runtime_enable(dev); ++ ++ return ret; ++} ++ ++static SIMPLE_DEV_PM_OPS(iproc_dma330_pm, iproc_dma330_suspend, iproc_dma330_resume); ++ ++static int ++iproc_dma330_probe(struct amba_device *adev, const struct amba_id *id) ++{ ++ struct dma_dma330_platdata *pdat; ++ struct dma330_config *pcfg; ++ struct dma330_dmac *dma330; ++ struct dma_dma330_chan *pch, *_p; ++ struct dma_device *pd; ++ struct resource *res; ++ int i, ret, irq; ++ int num_chan; ++ ++ pdat = dev_get_platdata(&adev->dev); ++ ++ ret = dma_set_mask_and_coherent(&adev->dev, DMA_BIT_MASK(32)); ++ if (ret) ++ return ret; ++ ++ /* Allocate a new DMAC and its Channels */ ++ dma330 = devm_kzalloc(&adev->dev, sizeof(*dma330), GFP_KERNEL); ++ if (!dma330) { ++ dev_err(&adev->dev, "unable to allocate mem\n"); ++ return -ENOMEM; ++ } ++ ++ pd = &dma330->ddma; ++ pd->dev = &adev->dev; ++ ++ dma330->mcbufsz = pdat ? pdat->mcbuf_sz : 0; ++ ++ res = &adev->res; ++ dma330->base = devm_ioremap_resource(&adev->dev, res); ++ if (IS_ERR(dma330->base)) ++ return PTR_ERR(dma330->base); ++ ++ amba_set_drvdata(adev, dma330); ++ ++ for (i = 0; i < AMBA_NR_IRQS; i++) { ++ irq = adev->irq[i]; ++ if (irq) { ++ ret = devm_request_irq(&adev->dev, irq, ++ dma330_irq_handler, 0, ++ dev_name(&adev->dev), dma330); ++ if (ret) ++ return ret; ++ } else { ++ break; ++ } ++ } ++ ++ pcfg = &dma330->pcfg; ++ ++ pcfg->periph_id = adev->periphid; ++ ret = dma330_add(dma330); ++ if (ret) ++ return ret; ++ ++ INIT_LIST_HEAD(&dma330->desc_pool); ++ spin_lock_init(&dma330->pool_lock); ++ ++ /* Create a descriptor pool of default size */ ++ if (!add_desc(dma330, GFP_KERNEL, NR_DEFAULT_DESC)) ++ dev_warn(&adev->dev, "unable to allocate desc\n"); ++ ++ INIT_LIST_HEAD(&pd->channels); ++ ++ /* Initialize channel parameters */ ++ if (pdat) ++ num_chan = max_t(int, pdat->nr_valid_peri, pcfg->num_chan); ++ else ++ num_chan = max_t(int, pcfg->num_peri, pcfg->num_chan); ++ ++ dma330->num_peripherals = num_chan; ++ ++ dma330->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL); ++ if (!dma330->peripherals) { ++ ret = -ENOMEM; ++ dev_err(&adev->dev, "unable to allocate dma330->peripherals\n"); ++ goto probe_err2; ++ } ++ ++ for (i = 0; i < num_chan; i++) { ++ pch = &dma330->peripherals[i]; ++ if (!adev->dev.of_node) ++ pch->chan.private = pdat ? &pdat->peri_id[i] : NULL; ++ else ++ pch->chan.private = adev->dev.of_node; ++ ++ INIT_LIST_HEAD(&pch->submitted_list); ++ INIT_LIST_HEAD(&pch->work_list); ++ INIT_LIST_HEAD(&pch->completed_list); ++ spin_lock_init(&pch->lock); ++ pch->thread = NULL; ++ pch->chan.device = pd; ++ pch->dmac = dma330; ++ ++ /* Add the channel to the DMAC list */ ++ list_add_tail(&pch->chan.device_node, &pd->channels); ++ } ++ ++ if (pdat) { ++ pd->cap_mask = pdat->cap_mask; ++ } else { ++ dma_cap_set(DMA_MEMCPY, pd->cap_mask); ++ if (pcfg->num_peri) { ++ dma_cap_set(DMA_SLAVE, pd->cap_mask); ++ dma_cap_set(DMA_CYCLIC, pd->cap_mask); ++ dma_cap_set(DMA_PRIVATE, pd->cap_mask); ++ } ++ } ++ ++ pd->device_alloc_chan_resources = dma330_alloc_chan_resources; ++ pd->device_free_chan_resources = dma330_free_chan_resources; ++ pd->device_prep_dma_memcpy = dma330_prep_dma_memcpy; ++ pd->device_prep_dma_cyclic = dma330_prep_dma_cyclic; ++ pd->device_tx_status = dma330_tx_status; ++ pd->device_prep_slave_sg = dma330_prep_slave_sg; ++ pd->device_config = dma330_config; ++ pd->device_pause = dma330_pause; ++ pd->device_terminate_all = dma330_terminate_all; ++ pd->device_issue_pending = dma330_issue_pending; ++ pd->src_addr_widths = DMA330_DMA_BUSWIDTHS; ++ pd->dst_addr_widths = DMA330_DMA_BUSWIDTHS; ++ pd->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); ++ pd->residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT; ++ ++ ret = dma_async_device_register(pd); ++ if (ret) { ++ dev_err(&adev->dev, "unable to register DMAC\n"); ++ goto probe_err3; ++ } ++ ++ if (adev->dev.of_node) { ++ ret = of_dma_controller_register(adev->dev.of_node, ++ of_dma_dma330_xlate, dma330); ++ if (ret) { ++ dev_err(&adev->dev, ++ "unable to register DMA to the generic DT DMA helpers\n"); ++ } ++ } ++ ++ adev->dev.dma_parms = &dma330->dma_parms; ++ ++ /* ++ * This is the limit for transfers with a buswidth of 1, larger ++ * buswidths will have larger limits. ++ */ ++ ret = dma_set_max_seg_size(&adev->dev, 1900800); ++ if (ret) ++ dev_err(&adev->dev, "unable to set the seg size\n"); ++ ++ ++ dev_info(&adev->dev, ++ "Loaded driver for DMA330 DMAC-%x\n", adev->periphid); ++ dev_info(&adev->dev, ++ "\tDBUFF-%ux%ubytes Num_Chans-%u Num_Peri-%u Num_Events-%u\n", ++ pcfg->data_buf_dep, pcfg->data_bus_width / 8, pcfg->num_chan, ++ pcfg->num_peri, pcfg->num_events); ++ ++ pm_runtime_irq_safe(&adev->dev); ++ pm_runtime_use_autosuspend(&adev->dev); ++ pm_runtime_set_autosuspend_delay(&adev->dev, DMA330_AUTOSUSPEND_DELAY); ++ pm_runtime_mark_last_busy(&adev->dev); ++ pm_runtime_put_autosuspend(&adev->dev); ++ ++ return 0; ++probe_err3: ++ /* Idle the DMAC */ ++ list_for_each_entry_safe(pch, _p, &dma330->ddma.channels, ++ chan.device_node) { ++ ++ /* Remove the channel */ ++ list_del(&pch->chan.device_node); ++ ++ /* Flush the channel */ ++ if (pch->thread) { ++ dma330_terminate_all(&pch->chan); ++ dma330_free_chan_resources(&pch->chan); ++ } ++ } ++probe_err2: ++ dma330_del(dma330); ++ ++ return ret; ++} ++ ++static int iproc_dma330_remove(struct amba_device *adev) ++{ ++ struct dma330_dmac *dma330 = amba_get_drvdata(adev); ++ struct dma_dma330_chan *pch, *_p; ++ ++ pm_runtime_get_noresume(dma330->ddma.dev); ++ ++ if (adev->dev.of_node) ++ of_dma_controller_free(adev->dev.of_node); ++ ++ dma_async_device_unregister(&dma330->ddma); ++ ++ /* Idle the DMAC */ ++ list_for_each_entry_safe(pch, _p, &dma330->ddma.channels, ++ chan.device_node) { ++ ++ /* Remove the channel */ ++ list_del(&pch->chan.device_node); ++ ++ /* Flush the channel */ ++ if (pch->thread) { ++ dma330_terminate_all(&pch->chan); ++ dma330_free_chan_resources(&pch->chan); ++ } ++ } ++ ++ dma330_del(dma330); ++ ++ return 0; ++} ++ ++static struct amba_id iproc_dma330_ids[] = { ++ { ++ .id = 0x00241330, ++ .mask = 0x00ffffff, ++ }, ++ { 0, 0 }, ++}; ++ ++MODULE_DEVICE_TABLE(amba, iproc_dma330_ids); ++ ++static struct amba_driver iproc_dma330_driver = { ++ .drv = { ++ .owner = THIS_MODULE, ++ .name = "dma-dma330", ++ .pm = &iproc_dma330_pm, ++ }, ++ .id_table = iproc_dma330_ids, ++ .probe = iproc_dma330_probe, ++ .remove = iproc_dma330_remove, ++}; ++ ++module_amba_driver(iproc_dma330_driver); ++ ++MODULE_DESCRIPTION("API Driver for DMA330 DMAC"); ++MODULE_LICENSE("GPL"); +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig +--- a/drivers/gpio/Kconfig 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/gpio/Kconfig 2017-11-09 17:53:27.600169000 +0800 +@@ -142,6 +142,15 @@ config GPIO_BRCMSTB + help + Say yes here to enable GPIO support for Broadcom STB (BCM7XXX) SoCs. + ++config GPIO_XGS_IPROC ++ tristate "BRCM XGS iProc GPIO support" ++ default y if ARCH_XGS_IPROC ++ depends on OF_GPIO && (ARCH_XGS_IPROC || COMPILE_TEST) ++ select GPIO_GENERIC ++ select GPIOLIB_IRQCHIP ++ help ++ Say yes here to enable GPIO support for Broadcom XGS iProc SoCs. ++ + config GPIO_CLPS711X + tristate "CLPS711X GPIO support" + depends on ARCH_CLPS711X || COMPILE_TEST +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/gpio/Makefile b/drivers/gpio/Makefile +--- a/drivers/gpio/Makefile 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/gpio/Makefile 2017-11-09 17:53:27.601169000 +0800 +@@ -25,6 +25,7 @@ obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizo + obj-$(CONFIG_ATH79) += gpio-ath79.o + obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o + obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o ++obj-$(CONFIG_GPIO_XGS_IPROC) += gpio-xgs-iproc.o + obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o + obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o + obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/gpio/gpio-xgs-iproc.c b/drivers/gpio/gpio-xgs-iproc.c +--- a/drivers/gpio/gpio-xgs-iproc.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/gpio/gpio-xgs-iproc.c 2017-11-09 17:53:27.757170000 +0800 +@@ -0,0 +1,815 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include "gpio-xgs-iproc.h" ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37) ++#define irq_get_chip_data get_irq_chip_data ++#define irq_set_chip_data set_irq_chip_data ++#define irq_set_chip set_irq_chip ++#define irq_set_handler set_irq_handler ++#define status_use_accessors status ++#endif ++ ++ ++#define IPROC_CCA_INT_F_GPIOINT 1 ++#define IPROC_CCA_INT_MASK 0x24 ++#define IPROC_GPIO_CCA_DIN 0x0 ++#define IPROC_GPIO_CCA_INT_LEVEL 0x10 ++#define IPROC_GPIO_CCA_INT_LEVEL_MASK 0x14 ++#define IPROC_GPIO_CCA_INT_EVENT 0x18 ++#define IPROC_GPIO_CCA_INT_EVENT_MASK 0x1C ++#define IPROC_CCA_INT_STS 0x20 ++#define IPROC_GPIO_CCA_INT_EDGE 0x24 ++ ++#define IPROC_GPIO_CCB_INT_TYPE 0xC ++#define IPROC_GPIO_CCB_INT_DE 0x10 ++#define IPROC_GPIO_CCB_INT_EDGE 0x14 ++#define IPROC_GPIO_CCB_INT_MSTAT 0x20 ++#define IPROC_GPIO_CCB_INT_CLR 0x24 ++#define IPROC_GPIO_CCB_INT_MASK 0x18 ++ ++ ++static unsigned int _iproc_gpio_readl(struct iproc_gpio_chip *chip, int reg) ++{ ++ return readl(chip->ioaddr + reg); ++} ++ ++static void _iproc_gpio_writel(struct iproc_gpio_chip *chip, unsigned int val, int reg) ++{ ++ writel(val, chip->ioaddr + reg); ++} ++ ++ ++/* ++@ pin : the actual pin number of the gpiochip ++*/ ++static int iproc_gpio_to_irq(struct iproc_gpio_chip *chip, unsigned int pin) { ++ return irq_linear_revmap(chip->irq_domain, pin - chip->pin_offset); ++} ++ ++/* ++returns the actual pin number of the gpiochip ++*/ ++static int iproc_irq_to_gpio(struct iproc_gpio_chip *chip, unsigned int irq) { ++ struct irq_data *data = irq_domain_get_irq_data(chip->irq_domain, irq); ++ ++ return data->hwirq + chip->pin_offset; ++} ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 5) ++static void iproc_gpio_irq_ack(unsigned int irq) ++{ ++#else ++static void iproc_gpio_irq_ack(struct irq_data *d) ++{ ++ unsigned int irq = d->irq; ++#endif ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ ++ if (ourchip) { ++ struct iproc_gpio_irqcfg *irqcfg = ourchip->irqcfg; ++ if (irqcfg && irqcfg->ack) ++ irqcfg->ack(irq); ++ ++ } ++} ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 5) ++static void iproc_gpio_irq_unmask(unsigned int irq) ++{ ++#else ++static void iproc_gpio_irq_unmask(struct irq_data *d) ++{ ++ unsigned int irq = d->irq; ++#endif ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ ++ if (ourchip) { ++ struct iproc_gpio_irqcfg *irqcfg = ourchip->irqcfg; ++ if (irqcfg && irqcfg->unmask) ++ irqcfg->unmask(irq); ++ } ++} ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 5) ++static void iproc_gpio_irq_mask(unsigned int irq) ++{ ++#else ++static void iproc_gpio_irq_mask(struct irq_data *d) ++{ ++ unsigned int irq = d->irq; ++#endif ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ ++ if (ourchip) { ++ struct iproc_gpio_irqcfg *irqcfg = ourchip->irqcfg; ++ if (irqcfg && irqcfg->mask) ++ irqcfg->mask(irq); ++ } ++} ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 5) ++static int iproc_gpio_irq_set_type(unsigned int irq, unsigned int type) ++{ ++#else ++static int iproc_gpio_irq_set_type(struct irq_data *d, unsigned int type) ++{ ++ unsigned int irq = d->irq; ++#endif ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ ++ if (ourchip) { ++ struct iproc_gpio_irqcfg *irqcfg = ourchip->irqcfg; ++ if (irqcfg && irqcfg->set_type) ++ return irqcfg->set_type(irq, type); ++ } ++ return -EINVAL; ++} ++ ++#if defined(IPROC_GPIO_CCA) ++static irqreturn_t iproc_gpio_irq_handler_cca(int irq, void *data) ++{ ++ struct iproc_gpio_chip *iproc_gpio = (struct iproc_gpio_chip *)data; ++ struct gpio_chip gc = iproc_gpio->chip; ++ int bit; ++ unsigned long int_bits = 0; ++ u32 int_status; ++ ++ /* go through the entire GPIOs and handle all interrupts */ ++ int_status = readl(iproc_gpio->intr_ioaddr + IPROC_CCA_INT_STS); ++ if (int_status & IPROC_CCA_INT_F_GPIOINT) { ++ unsigned int event, level; ++ ++ /* Get level and edge interrupts */ ++ event = readl(iproc_gpio->ioaddr + IPROC_GPIO_CCA_INT_EVENT_MASK) & readl(iproc_gpio->ioaddr + IPROC_GPIO_CCA_INT_EVENT); ++ level = readl(iproc_gpio->ioaddr + IPROC_GPIO_CCA_DIN) ^ ++ readl(iproc_gpio->ioaddr + IPROC_GPIO_CCA_INT_LEVEL); ++ level &= readl(iproc_gpio->ioaddr + IPROC_GPIO_CCA_INT_LEVEL_MASK); ++ int_bits = level | event; ++ ++ for_each_set_bit(bit, &int_bits, gc.ngpio) ++ generic_handle_irq( ++ irq_linear_revmap(iproc_gpio->irq_domain, bit)); ++ } ++ ++ return int_bits ? IRQ_HANDLED : IRQ_NONE; ++} ++ ++ ++static void iproc_gpio_irq_ack_cca(unsigned int irq) ++{ ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ int pin; ++ ++ pin = iproc_irq_to_gpio(ourchip, irq); ++ ++ if (ourchip->id == IPROC_GPIO_CCA_ID) { ++ unsigned int event_status, irq_type; ++ ++ event_status = 0; ++ irq_type = irq_get_trigger_type(irq); ++ if (irq_type & IRQ_TYPE_EDGE_BOTH) ++ { ++ event_status |= (1 << pin); ++ _iproc_gpio_writel(ourchip, event_status, ++ IPROC_GPIO_CCA_INT_EVENT); ++ } ++ ++ } ++} ++ ++static void iproc_gpio_irq_unmask_cca(unsigned int irq) ++{ ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ int pin; ++ unsigned int int_mask, irq_type; ++ ++ pin = iproc_irq_to_gpio(ourchip, irq); ++ irq_type = irq_get_trigger_type(irq); ++ ++ if (ourchip->id == IPROC_GPIO_CCA_ID) { ++ unsigned int event_mask; ++ ++ event_mask = _iproc_gpio_readl(ourchip, IPROC_GPIO_CCA_INT_EVENT_MASK); ++ int_mask = _iproc_gpio_readl(ourchip, IPROC_GPIO_CCA_INT_LEVEL_MASK); ++ ++ if (irq_type & IRQ_TYPE_EDGE_BOTH) { ++ event_mask |= 1 << pin; ++ _iproc_gpio_writel(ourchip, event_mask, ++ IPROC_GPIO_CCA_INT_EVENT_MASK); ++ } else { ++ int_mask |= 1 << pin; ++ _iproc_gpio_writel(ourchip, int_mask, ++ IPROC_GPIO_CCA_INT_LEVEL_MASK); ++ } ++ } ++ ++} ++ ++static void iproc_gpio_irq_mask_cca(unsigned int irq) ++{ ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ int pin; ++ unsigned int irq_type, int_mask; ++ ++ pin = iproc_irq_to_gpio(ourchip, irq); ++ irq_type = irq_get_trigger_type(irq); ++ ++ if (ourchip->id == IPROC_GPIO_CCA_ID) { ++ unsigned int event_mask; ++ ++ event_mask = _iproc_gpio_readl(ourchip, IPROC_GPIO_CCA_INT_EVENT_MASK); ++ int_mask = _iproc_gpio_readl(ourchip, IPROC_GPIO_CCA_INT_LEVEL_MASK); ++ ++ if (irq_type & IRQ_TYPE_EDGE_BOTH) { ++ event_mask &= ~(1 << pin); ++ _iproc_gpio_writel(ourchip, event_mask, ++ IPROC_GPIO_CCA_INT_EVENT_MASK); ++ } else { ++ int_mask &= ~(1 << pin); ++ _iproc_gpio_writel(ourchip, int_mask, ++ IPROC_GPIO_CCA_INT_LEVEL_MASK); ++ } ++ } ++} ++ ++static int iproc_gpio_irq_set_type_cca(unsigned int irq, unsigned int type) ++{ ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ int pin; ++ ++ pin = iproc_irq_to_gpio(ourchip, irq); ++ ++ if (ourchip->id == IPROC_GPIO_CCA_ID) { ++ unsigned int event_pol, int_pol; ++ ++ switch (type & IRQ_TYPE_SENSE_MASK) { ++ case IRQ_TYPE_EDGE_RISING: ++ event_pol = _iproc_gpio_readl(ourchip, IPROC_GPIO_CCA_INT_EDGE); ++ event_pol &= ~(1 << pin); ++ _iproc_gpio_writel(ourchip, event_pol, IPROC_GPIO_CCA_INT_EDGE); ++ break; ++ case IRQ_TYPE_EDGE_FALLING: ++ event_pol = _iproc_gpio_readl(ourchip, IPROC_GPIO_CCA_INT_EDGE); ++ event_pol |= (1 << pin); ++ _iproc_gpio_writel(ourchip, event_pol, IPROC_GPIO_CCA_INT_EDGE); ++ break; ++ case IRQ_TYPE_LEVEL_HIGH: ++ int_pol = _iproc_gpio_readl(ourchip, IPROC_GPIO_CCA_INT_LEVEL); ++ int_pol &= ~(1 << pin); ++ _iproc_gpio_writel(ourchip, int_pol, IPROC_GPIO_CCA_INT_LEVEL); ++ break; ++ case IRQ_TYPE_LEVEL_LOW: ++ int_pol = _iproc_gpio_readl(ourchip,IPROC_GPIO_CCA_INT_LEVEL); ++ int_pol |= (1 << pin); ++ _iproc_gpio_writel(ourchip, int_pol, IPROC_GPIO_CCA_INT_LEVEL); ++ break; ++ default: ++ printk(KERN_ERR "unsupport irq type !\n"); ++ return -EINVAL; ++ } ++ } ++ ++ if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) ++ irq_set_handler_locked(irq_get_irq_data(irq), handle_level_irq); ++ else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) ++ irq_set_handler_locked(irq_get_irq_data(irq), handle_edge_irq); ++ ++ return 0; ++} ++ ++struct iproc_gpio_irqcfg cca_gpio_irqcfg = { ++ /* Remove IRQF_NO_SUSPEND to be consistent with 8250_core.c setting ++ * since CCA gpio and uart share the same IRQ. ++ */ ++ .flags = IRQF_SHARED, ++ .handler = iproc_gpio_irq_handler_cca, ++ .ack = iproc_gpio_irq_ack_cca, ++ .mask = iproc_gpio_irq_mask_cca, ++ .unmask = iproc_gpio_irq_unmask_cca, ++ .set_type = iproc_gpio_irq_set_type_cca, ++}; ++#endif /* IPROC_GPIO_CCA */ ++ ++#if defined(IPROC_GPIO_CCB) || defined(IPROC_GPIO_CCG) ++static irqreturn_t ++iproc_gpio_irq_handler_ccb(int irq, void *dev) ++{ ++ struct iproc_gpio_chip *ourchip = dev; ++ int iter, max_pin; ++ unsigned int val; ++ ++ val = _iproc_gpio_readl(ourchip, IPROC_GPIO_CCB_INT_MSTAT); ++ if(!val){ ++ return IRQ_NONE; ++ } ++ ++ max_pin = ourchip->pin_offset + ourchip->chip.ngpio; ++ for (iter = ourchip->pin_offset; iter < max_pin; iter ++) { ++ if (val & (1 << iter)) { ++ //writel(1 << iter, ourchip->ioaddr + IPROC_GPIO_CCB_INT_CLR); ++ generic_handle_irq(iproc_gpio_to_irq(ourchip, iter)); ++ } ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++static void iproc_gpio_irq_ack_ccb(unsigned int irq) ++{ ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ int pin; ++ ++ pin = iproc_irq_to_gpio(ourchip, irq); ++ ++ if ((ourchip->id == IPROC_GPIO_CCB_ID) || ++ (ourchip->id == IPROC_GPIO_CCG_ID)) { ++ unsigned int int_clear = 0; ++ ++ int_clear |= (1 << pin); ++ _iproc_gpio_writel(ourchip, int_clear, IPROC_GPIO_CCB_INT_CLR); ++ ++ } ++} ++ ++static void iproc_gpio_irq_unmask_ccb(unsigned int irq) ++{ ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ int pin; ++ unsigned int int_mask; ++ ++ pin = iproc_irq_to_gpio(ourchip, irq); ++ ++ if ((ourchip->id == IPROC_GPIO_CCB_ID) || ++ (ourchip->id == IPROC_GPIO_CCG_ID)) { ++ int_mask = _iproc_gpio_readl(ourchip, IPROC_GPIO_CCB_INT_MASK); ++ int_mask |= (1 << pin); ++ _iproc_gpio_writel(ourchip, int_mask, IPROC_GPIO_CCB_INT_MASK); ++ } ++ ++} ++ ++static void iproc_gpio_irq_mask_ccb(unsigned int irq) ++{ ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ int pin; ++ unsigned int int_mask; ++ ++ pin = iproc_irq_to_gpio(ourchip, irq); ++ ++ if ((ourchip->id == IPROC_GPIO_CCB_ID) || ++ (ourchip->id == IPROC_GPIO_CCG_ID)) { ++ int_mask = _iproc_gpio_readl(ourchip, IPROC_GPIO_CCB_INT_MASK); ++ int_mask &= ~(1 << pin); ++ _iproc_gpio_writel(ourchip, int_mask,IPROC_GPIO_CCB_INT_MASK); ++ } ++} ++ ++static int iproc_gpio_irq_set_type_ccb(unsigned int irq, unsigned int type) ++{ ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ int pin; ++ ++ ++ pin = iproc_irq_to_gpio(ourchip, irq); ++ ++ if ((ourchip->id == IPROC_GPIO_CCB_ID) || ++ (ourchip->id == IPROC_GPIO_CCG_ID)) { ++ unsigned int int_type, int_de, int_edge; ++ int_type = _iproc_gpio_readl(ourchip, IPROC_GPIO_CCB_INT_TYPE); ++ int_edge = _iproc_gpio_readl(ourchip, IPROC_GPIO_CCB_INT_EDGE); ++ switch (type) { ++ case IRQ_TYPE_EDGE_BOTH: ++ int_type &= ~(1 << pin); ++ int_de = _iproc_gpio_readl(ourchip, IPROC_GPIO_CCB_INT_DE); ++ int_de |= (1 << pin); ++ _iproc_gpio_writel(ourchip, int_de, IPROC_GPIO_CCB_INT_DE); ++ break; ++ case IRQ_TYPE_EDGE_RISING: ++ int_type &= ~(1 << pin); ++ int_edge |= (1 << pin); ++ ++ int_de = _iproc_gpio_readl(ourchip, IPROC_GPIO_CCB_INT_DE); ++ int_de &= ~(1 << pin); ++ _iproc_gpio_writel(ourchip, int_de, IPROC_GPIO_CCB_INT_DE); ++ break; ++ case IRQ_TYPE_EDGE_FALLING: ++ int_type &= ~(1 << pin); ++ int_edge &= ~(1 << pin); ++ ++ int_de = _iproc_gpio_readl(ourchip, IPROC_GPIO_CCB_INT_DE); ++ int_de &= ~(1 << pin); ++ _iproc_gpio_writel(ourchip, int_de, IPROC_GPIO_CCB_INT_DE); ++ break; ++ case IRQ_TYPE_LEVEL_HIGH: ++ int_type |= (1 << pin); ++ int_edge |= (1 << pin); ++ break; ++ case IRQ_TYPE_LEVEL_LOW: ++ int_type |= (1 << pin); ++ int_edge &= ~(1 << pin); ++ break; ++ default: ++ printk(KERN_ERR "unsupport irq type !\n"); ++ return -EINVAL; ++ } ++ _iproc_gpio_writel(ourchip, int_type, IPROC_GPIO_CCB_INT_TYPE); ++ _iproc_gpio_writel(ourchip, int_edge, IPROC_GPIO_CCB_INT_EDGE); ++ } ++ ++ if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) ++ irq_set_handler_locked(irq_get_irq_data(irq), handle_level_irq); ++ else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) ++ irq_set_handler_locked(irq_get_irq_data(irq), handle_edge_irq); ++ ++ return 0; ++} ++ ++struct iproc_gpio_irqcfg ccb_gpio_irqcfg = { ++ .flags = IRQF_NO_SUSPEND, ++ .handler = iproc_gpio_irq_handler_ccb, ++ .ack = iproc_gpio_irq_ack_ccb, ++ .mask = iproc_gpio_irq_mask_ccb, ++ .unmask = iproc_gpio_irq_unmask_ccb, ++ .set_type = iproc_gpio_irq_set_type_ccb, ++}; ++#endif /* IPROC_GPIO_CCB || IPROC_GPIO_CCG*/ ++ ++static struct irq_chip iproc_gpio_irq_chip = { ++ .name = "IPROC-GPIO", ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 5) ++ .ack = (void *) iproc_gpio_irq_ack, ++ .mask = (void *) iproc_gpio_irq_mask, ++ .unmask = (void *) iproc_gpio_irq_unmask, ++ .set_type = (void *) iproc_gpio_irq_set_type, ++#else ++ .irq_ack = (void *) iproc_gpio_irq_ack, ++ .irq_mask = (void *) iproc_gpio_irq_mask, ++ .irq_unmask = (void *) iproc_gpio_irq_unmask, ++ .irq_set_type = (void *) iproc_gpio_irq_set_type, ++#endif ++}; ++ ++ ++static int iproc_gpiolib_input(struct gpio_chip *chip, unsigned gpio) ++{ ++ struct iproc_gpio_chip *ourchip = to_iproc_gpio(chip); ++ unsigned long flags; ++ unsigned int val, nBitMask; ++ int reg_offset; ++ unsigned int pin_offset = gpio + ourchip->pin_offset; ++ ++ iproc_gpio_lock(ourchip, flags); ++ ++ nBitMask = 1 << pin_offset; ++ reg_offset = REGOFFSET_GPIO_EN; ++ ++ val = _iproc_gpio_readl(ourchip, reg_offset); ++ val &= ~nBitMask; ++ _iproc_gpio_writel(ourchip, val, reg_offset); ++ ++ iproc_gpio_unlock(ourchip, flags); ++ return 0; ++} ++ ++static int iproc_gpiolib_output(struct gpio_chip *chip, ++ unsigned gpio, int value) ++{ ++ struct iproc_gpio_chip *ourchip = to_iproc_gpio(chip); ++ unsigned long flags, val; ++ unsigned int nBitMask; ++ int reg_offset; ++ unsigned int pin_offset = gpio + ourchip->pin_offset; ++ ++ iproc_gpio_lock(ourchip, flags); ++ ++ nBitMask = 1 << pin_offset; ++ reg_offset = REGOFFSET_GPIO_EN; ++ ++ val = _iproc_gpio_readl(ourchip, reg_offset); ++ val |= nBitMask; ++ _iproc_gpio_writel(ourchip, val, reg_offset); ++ ++ iproc_gpio_unlock(ourchip, flags); ++ return 0; ++} ++ ++static void iproc_gpiolib_set(struct gpio_chip *chip, ++ unsigned gpio, int value) ++{ ++ struct iproc_gpio_chip *ourchip = to_iproc_gpio(chip); ++ unsigned long flags, val; ++ unsigned int nBitMask; ++ int reg_offset = 0; ++ unsigned int pin_offset = gpio + ourchip->pin_offset; ++ ++ iproc_gpio_lock(ourchip, flags); ++ ++ nBitMask = 1 << pin_offset; ++ ++ val = _iproc_gpio_readl(ourchip, REGOFFSET_GPIO_EN + reg_offset); ++ val &= nBitMask; ++ ++ /* this function only applies to output pin ++ */ ++ if (!val) ++ return; ++ ++ val = _iproc_gpio_readl(ourchip, REGOFFSET_GPIO_DOUT + reg_offset); ++ ++ if ( value == 0 ){ ++ /* Set the pin to zero */ ++ val &= ~nBitMask; ++ }else{ ++ /* Set the pin to 1 */ ++ val |= nBitMask; ++ } ++ _iproc_gpio_writel(ourchip, val, REGOFFSET_GPIO_DOUT + reg_offset); ++ ++ iproc_gpio_unlock(ourchip, flags); ++ ++} ++ ++ ++static int iproc_gpiolib_get(struct gpio_chip *chip, unsigned gpio) ++{ ++ struct iproc_gpio_chip *ourchip = to_iproc_gpio(chip); ++ unsigned long flags; ++ unsigned int val, offset, nBitMask; ++ int reg_offset = 0; ++ unsigned int pin_offset = gpio + ourchip->pin_offset; ++ ++ iproc_gpio_lock(ourchip, flags); ++ ++ nBitMask = 1 << pin_offset; ++ ++ /* determine the GPIO pin direction ++ */ ++ offset = _iproc_gpio_readl(ourchip, REGOFFSET_GPIO_EN + reg_offset); ++ offset &= nBitMask; ++ ++ if (offset){ ++ val = _iproc_gpio_readl(ourchip, REGOFFSET_GPIO_DOUT + reg_offset); ++ } else { ++ val = _iproc_gpio_readl(ourchip, REGOFFSET_GPIO_DIN + reg_offset); ++ } ++ ++ val >>= pin_offset; ++ ++ val &= 1; ++ ++ iproc_gpio_unlock(ourchip, flags); ++ ++ return val; ++} ++ ++/* ++@offset : the gpio pin index number from gpiolib view (minus gpio base only) ++*/ ++static int iproc_gpiolib_to_irq(struct gpio_chip *chip, ++ unsigned offset) ++{ ++ struct iproc_gpio_chip *ourchip = to_iproc_gpio(chip); ++ return irq_linear_revmap(ourchip->irq_domain, offset); ++} ++ ++static struct __initconst of_device_id bcm_iproc_gpio_of_match[] = { ++ { .compatible = "brcm,iproc-gpio,cca" }, ++ { .compatible = "brcm,iproc-gpio,ccb" }, ++ { .compatible = "brcm,iproc-gpio,ccg" }, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, bcm_iproc_gpio_of_match); ++ ++void iproc_gpiolib_add(struct iproc_gpio_chip *chip) ++{ ++ struct gpio_chip *gc = &chip->chip; ++ int ret; ++ ++ BUG_ON(!gc->label); ++ BUG_ON(!gc->ngpio); ++ ++ /* ++ * The register offsets for data in, out, and enable are the same for ++ * all GPIO's. ++ */ ++ if (!gc->direction_input) ++ gc->direction_input = iproc_gpiolib_input; ++ if (!gc->direction_output) ++ gc->direction_output = iproc_gpiolib_output; ++ if (!gc->set) ++ gc->set = iproc_gpiolib_set; ++ if (!gc->get) ++ gc->get = iproc_gpiolib_get; ++ if (!gc->to_irq) ++ gc->to_irq = iproc_gpiolib_to_irq; ++ ++ ret = gpiochip_add(gc); ++ if (ret >= 0) ++ printk(KERN_INFO "iproc gpiochip add %s\n", gc->label); ++ ++ return; ++} ++ ++/* ++ * Handles CCA, CCB, and CCG type GPIO's and registers the gpio ++ * controller. ++ */ ++ ++static int iproc_gpio_probe(struct platform_device *pdev) ++{ ++ const struct of_device_id *match; ++ struct device_node *dn = pdev->dev.of_node; ++ struct iproc_gpio_chip *iproc_gpio; ++ u32 num_gpios, pin_base, pin_offset, count/*, irq_base*/; ++ int ret; ++ ++ match = of_match_device(bcm_iproc_gpio_of_match, &pdev->dev); ++ if (!match) { ++ dev_err(&pdev->dev, "Failed to find gpio controller\n"); ++ return -ENODEV; ++ } ++ ++ iproc_gpio = devm_kzalloc(&pdev->dev, sizeof(*iproc_gpio), GFP_KERNEL); ++ if (!iproc_gpio) { ++ dev_err(&pdev->dev, "Error allocating memory\n"); ++ return -ENOMEM; ++ } ++ ++ platform_set_drvdata(pdev, iproc_gpio); ++ ++ /* Determine type of gpio controller to allocate. */ ++#if defined(IPROC_GPIO_CCA) ++ if (strstr(match->compatible, "cca")) { ++ iproc_gpio->chip.label = "gpio_cca"; ++ iproc_gpio->id = IPROC_GPIO_CCA_ID; ++ iproc_gpio->irqcfg = &cca_gpio_irqcfg; ++ ++ iproc_gpio->intr_ioaddr = of_iomap(dn, 1); ++ if (!iproc_gpio->intr_ioaddr) { ++ dev_err(&pdev->dev, "can't iomap gpio interrupt base address\n"); ++ return -ENOMEM; ++ } ++ ++ dev_info(&pdev->dev, "%s intr_ioaddr: %p\n", ++ iproc_gpio->chip.label, iproc_gpio->intr_ioaddr); ++ } ++ else ++#endif ++#if defined(IPROC_GPIO_CCB) ++ if (strstr(match->compatible, "ccb")) { ++ iproc_gpio->chip.label = "gpio_ccb"; ++ iproc_gpio->id = IPROC_GPIO_CCB_ID; ++ iproc_gpio->irqcfg = &ccb_gpio_irqcfg; ++ } ++ else ++#endif ++#if defined(IPROC_GPIO_CCG) ++ if (strstr(match->compatible, "ccg")) { ++ iproc_gpio->chip.label = "gpio_ccg"; ++ iproc_gpio->id = IPROC_GPIO_CCG_ID; ++ iproc_gpio->irqcfg = &ccb_gpio_irqcfg; ++ } ++ else ++#endif ++ { ++ dev_err(&pdev->dev, "Error parsing device tree of GPIO\n"); ++ return -ENODEV; ++ } ++ ++ /* Map gpio base ioaddr address. */ ++ iproc_gpio->ioaddr = of_iomap(dn, 0); ++ if (!iproc_gpio->ioaddr) { ++ dev_err(&pdev->dev, "can't iomap gpio base address\n"); ++ return -ENOMEM; ++ } ++ dev_info(&pdev->dev, "%s iaddr: %p\n", iproc_gpio->chip.label, iproc_gpio->ioaddr); ++ ++ if (of_property_read_u32(dn, "pin-base", &pin_base)) { ++ dev_err(&pdev->dev, "Missing pin-base property\n"); ++ return -EINVAL; ++ } ++ iproc_gpio->chip.base = pin_base; ++ ++ /* get pin_offset */ ++ if (of_property_read_u32(dn, "pin-offset", &pin_offset)) { ++ dev_err(&pdev->dev, "Missing pin-offset property\n"); ++ return -EINVAL; ++ } ++ iproc_gpio->pin_offset = pin_offset; ++ ++ /* Get number of GPIO's from device tree for gpiolib. */ ++ if (of_property_read_u32(dn, "ngpios", &num_gpios)) { ++ dev_err(&pdev->dev, "Missing ngpios property\n"); ++ return -EINVAL; ++ } ++ iproc_gpio->chip.ngpio = num_gpios; ++ ++ /* Register controller with gpiolib. */ ++ iproc_gpio->chip.dev = &pdev->dev; ++ iproc_gpiolib_add(iproc_gpio); ++ ++ /* Get interrupt number from device tree. */ ++ iproc_gpio->irq = irq_of_parse_and_map(dn, 0); ++ ++ /* Install ISR for this GPIO controller. */ ++ if (iproc_gpio->irq > 0) { ++ /* Create irq domain so that each pin can be assigned an IRQ.*/ ++ iproc_gpio->irq_domain = irq_domain_add_linear(dn, num_gpios, ++ &irq_domain_simple_ops, iproc_gpio); ++ ++ if (!iproc_gpio->irq_domain) { ++ dev_err(&pdev->dev, "Couldn't allocate IRQ domain\n"); ++ return -ENXIO; ++ } ++ ++ /* Map each gpio to an IRQ and set the handler for gpiolib. */ ++ for (count = 0; count < num_gpios; count++) { ++ int irq; ++ ++ irq = irq_create_mapping(iproc_gpio->irq_domain, count); ++ irq_set_chip_and_handler(irq, &iproc_gpio_irq_chip, ++ handle_simple_irq); ++ irq_set_chip_data(irq, iproc_gpio); ++ } ++ ++ /* Enable GPIO interrupts in CCA interrupt mask. */ ++#if defined(IPROC_GPIO_CCA) ++ if (iproc_gpio->id == IPROC_GPIO_CCA_ID) { ++ unsigned int val; ++ val = readl(iproc_gpio->intr_ioaddr + IPROC_CCA_INT_MASK); ++ val |= IPROC_CCA_INT_F_GPIOINT; ++ writel(val, iproc_gpio->intr_ioaddr + IPROC_CCA_INT_MASK); ++ } ++#endif /* IPROC_GPIO_CCA */ ++ if (iproc_gpio->irqcfg) { ++ struct iproc_gpio_irqcfg *irqcfg = iproc_gpio->irqcfg; ++ if (irqcfg->handler) { ++ ret = request_irq(iproc_gpio->irq, ++ irqcfg->handler, irqcfg->flags, ++ iproc_gpio->chip.label, iproc_gpio); ++ if (ret) { ++ printk(KERN_ERR "Unable to request IRQ%d: %d\n", iproc_gpio->irq, ret); ++ return -ENODEV; ++ } ++ } ++ else ++ printk(KERN_ERR "%s is added without isr!\n", iproc_gpio->chip.label); ++ } ++ } ++ else ++ dev_warn(&pdev->dev, "IRQ not specified. No ISR installed\n"); ++ ++ return 0; ++} ++ ++static int __exit iproc_gpio_remove(struct platform_device *pdev) ++{ ++ struct iproc_gpio_chip *iproc_gpio; ++ ++ iproc_gpio = platform_get_drvdata(pdev); ++ if (iproc_gpio == NULL) ++ return -ENODEV; ++ ++ if (iproc_gpio->intr_ioaddr) { ++#if defined(IPROC_GPIO_CCA) ++ if (iproc_gpio->id == IPROC_GPIO_CCA_ID) { ++ unsigned int val; ++ val = readl(iproc_gpio->intr_ioaddr + IPROC_CCA_INT_MASK); ++ val &= ~(IPROC_CCA_INT_F_GPIOINT); ++ writel(val, iproc_gpio->intr_ioaddr + IPROC_CCA_INT_MASK); ++ } ++#endif ++ } ++ ++ gpiochip_remove(&iproc_gpio->chip); ++ ++ return 0; ++} ++ ++static struct platform_driver bcm_iproc_gpio_driver = { ++ .driver = { ++ .name = "iproc-gpio", ++ .owner = THIS_MODULE, ++ .of_match_table = bcm_iproc_gpio_of_match, ++ }, ++ .probe = iproc_gpio_probe, ++ .remove = iproc_gpio_remove, ++}; ++ ++module_platform_driver(bcm_iproc_gpio_driver); ++ ++MODULE_DESCRIPTION("IPROC GPIO driver"); ++MODULE_LICENSE("GPL"); +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/gpio/gpio-xgs-iproc.h b/drivers/gpio/gpio-xgs-iproc.h +--- a/drivers/gpio/gpio-xgs-iproc.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/gpio/gpio-xgs-iproc.h 2017-11-09 17:53:27.757186000 +0800 +@@ -0,0 +1,61 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ */ ++ ++#ifndef __IPROC_PLAT_GPIO_H ++#define __IPROC_PLAT_GPIO_H ++ ++#if defined(CONFIG_MACH_IPROC_P7) ++#define IPROC_GPIO_CCG ++#else ++#define IPROC_GPIO_CCA ++#define IPROC_GPIO_CCB ++#endif ++ ++#define IPROC_GPIO_REG_SIZE (0x50) ++ ++#define REGOFFSET_GPIO_DIN 0x000 /* GPIO Data in register */ ++#define REGOFFSET_GPIO_DOUT 0x004 /* GPIO Data out register */ ++#define REGOFFSET_GPIO_EN 0x008 /* GPIO output enable register */ ++ ++#define IPROC_GPIO_CCA_ID (0) ++#define IPROC_GPIO_CCB_ID (1) ++#define IPROC_GPIO_CCG_ID (2) ++ ++struct iproc_gpio_irqcfg { ++ unsigned long flags; ++ irqreturn_t (*handler)(int irq, void *dev); ++ void (*ack)(unsigned int irq); ++ void (*unmask)(unsigned int irq); ++ void (*mask)(unsigned int irq); ++ int (*set_type)(unsigned int irq, unsigned int type); ++}; ++ ++struct iproc_gpio_chip { ++ int id; ++ struct gpio_chip chip; ++ struct iproc_gpio_cfg *config; ++ void __iomem *ioaddr; ++ void __iomem *intr_ioaddr; ++ spinlock_t lock; ++ struct irq_domain *irq_domain; ++ struct resource * resource; ++ int irq; ++ struct iproc_gpio_irqcfg *irqcfg; ++ int pin_offset; ++}; ++ ++ ++static inline struct iproc_gpio_chip *to_iproc_gpio(struct gpio_chip *gpc) ++{ ++ return container_of(gpc, struct iproc_gpio_chip, chip); ++} ++ ++ ++/* locking wrappers to deal with multiple access to the same gpio bank */ ++#define iproc_gpio_lock(_oc, _fl) spin_lock_irqsave(&(_oc)->lock, _fl) ++#define iproc_gpio_unlock(_oc, _fl) spin_unlock_irqrestore(&(_oc)->lock, _fl) ++ ++extern void iproc_gpiolib_add(struct iproc_gpio_chip *chip); ++ ++#endif +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig +--- a/drivers/i2c/busses/Kconfig 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/i2c/busses/Kconfig 2017-11-09 17:53:33.506215000 +0800 +@@ -385,6 +385,26 @@ config I2C_BCM_IPROC + + If you don't know what to do here, say N. + ++config I2C_XGS_IPROC ++ tristate "Broadcom XGS iProc I2C controller" ++ depends on ARCH_XGS_IPROC ++ default ARCH_XGS_IPROC ++ help ++ If you say yes to this option, support will be included for the ++ Broadcom XGS iProc I2C controller. ++ ++ If you don't know what to do here, say N. ++ ++config SMBUS_XGS_IPROC ++ tristate "Broadcom XGS iProc SMBUS controller" ++ depends on ARCH_XGS_IPROC ++ default !I2C_XGS_IPROC ++ help ++ If you say yes to this option, support will be included for the ++ Broadcom XGS iProc SMBUS controller. ++ ++ If you don't know what to do here, say N. ++ + config I2C_BCM_KONA + tristate "BCM Kona I2C adapter" + depends on ARCH_BCM_MOBILE +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile +--- a/drivers/i2c/busses/Makefile 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/i2c/busses/Makefile 2017-11-09 17:53:33.507214000 +0800 +@@ -92,6 +92,8 @@ obj-$(CONFIG_I2C_UNIPHIER_F) += i2c-unip + obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o + obj-$(CONFIG_I2C_WMT) += i2c-wmt.o + obj-$(CONFIG_I2C_OCTEON) += i2c-octeon.o ++obj-$(CONFIG_I2C_XGS_IPROC) += i2c-xgs-iproc.o ++obj-$(CONFIG_SMBUS_XGS_IPROC) += xgs_iproc_smbus.o + obj-$(CONFIG_I2C_XILINX) += i2c-xiic.o + obj-$(CONFIG_I2C_XLR) += i2c-xlr.o + obj-$(CONFIG_I2C_XLP9XX) += i2c-xlp9xx.o +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/i2c/busses/i2c-xgs-iproc.c b/drivers/i2c/busses/i2c-xgs-iproc.c +--- a/drivers/i2c/busses/i2c-xgs-iproc.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/i2c/busses/i2c-xgs-iproc.c 2017-11-09 17:53:33.700222000 +0800 +@@ -0,0 +1,598 @@ ++/* ++ * Copyright (C) 2014 Broadcom Corporation ++ * ++ * 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 version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define CFG_OFFSET 0x00 ++#define CFG_RESET_SHIFT 31 ++#define CFG_EN_SHIFT 30 ++#define CFG_M_RETRY_CNT_SHIFT 16 ++#define CFG_M_RETRY_CNT_MASK 0x0f ++ ++#define TIM_CFG_OFFSET 0x04 ++#define TIM_CFG_MODE_400_SHIFT 31 ++ ++#define M_FIFO_CTRL_OFFSET 0x0c ++#define M_FIFO_RX_FLUSH_SHIFT 31 ++#define M_FIFO_TX_FLUSH_SHIFT 30 ++#define M_FIFO_RX_CNT_SHIFT 16 ++#define M_FIFO_RX_CNT_MASK 0x7f ++#define M_FIFO_RX_THLD_SHIFT 8 ++#define M_FIFO_RX_THLD_MASK 0x3f ++ ++#define M_CMD_OFFSET 0x30 ++#define M_CMD_START_BUSY_SHIFT 31 ++#define M_CMD_STATUS_SHIFT 25 ++#define M_CMD_STATUS_MASK 0x07 ++#define M_CMD_STATUS_SUCCESS 0x0 ++#define M_CMD_STATUS_LOST_ARB 0x1 ++#define M_CMD_STATUS_NACK_ADDR 0x2 ++#define M_CMD_STATUS_NACK_DATA 0x3 ++#define M_CMD_STATUS_TIMEOUT 0x4 ++#define M_CMD_PROTOCOL_SHIFT 9 ++#define M_CMD_PROTOCOL_MASK 0xf ++#define M_CMD_PROTOCOL_BLK_WR 0x7 ++#define M_CMD_PROTOCOL_BLK_RD 0x8 ++#define M_CMD_PEC_SHIFT 8 ++#define M_CMD_RD_CNT_SHIFT 0 ++#define M_CMD_RD_CNT_MASK 0xff ++ ++#define IE_OFFSET 0x38 ++#define IE_M_RX_FIFO_FULL_SHIFT 31 ++#define IE_M_RX_THLD_SHIFT 30 ++#define IE_M_START_BUSY_SHIFT 28 ++ ++#define IS_OFFSET 0x3c ++#define IS_M_RX_FIFO_FULL_SHIFT 31 ++#define IS_M_RX_THLD_SHIFT 30 ++#define IS_M_START_BUSY_SHIFT 28 ++ ++#define M_TX_OFFSET 0x40 ++#define M_TX_WR_STATUS_SHIFT 31 ++#define M_TX_DATA_SHIFT 0 ++#define M_TX_DATA_MASK 0xff ++ ++#define M_RX_OFFSET 0x44 ++#define M_RX_STATUS_SHIFT 30 ++#define M_RX_STATUS_MASK 0x03 ++#define M_RX_PEC_ERR_SHIFT 29 ++#define M_RX_DATA_SHIFT 0 ++#define M_RX_DATA_MASK 0xff ++ ++#define I2C_TIMEOUT_MESC 100 ++ ++#define M_TX_RX_FIFO_SIZE 64 ++#define I2C_MAX_DATA_READ_LEN (M_TX_RX_FIFO_SIZE - 1) ++#define I2C_MAX_DATA_WRITE_LEN (M_TX_RX_FIFO_SIZE - 1) ++ ++/* ++ * Enable support of EEPROM I2C devices with 2 byte addressing mode and page ++ * size >= 64B. ++ */ ++#define CONFIG_ENABLE_WRITE_MSG_SPLIT 1 ++ ++ ++enum bus_speed_index { ++ I2C_SPD_100K = 0, ++ I2C_SPD_400K, ++}; ++ ++struct bcm_iproc_i2c_dev { ++ struct device *device; ++ int irq; ++ ++ void __iomem *base; ++ ++ struct i2c_adapter adapter; ++ unsigned int bus_speed; ++ ++ struct completion done; ++ int xfer_is_done; ++}; ++ ++/* ++ * Can be expanded in the future if more interrupt status bits are utilized ++ */ ++#define ISR_MASK (1 << IS_M_START_BUSY_SHIFT) ++ ++static irqreturn_t bcm_iproc_i2c_isr(int irq, void *data) ++{ ++ struct bcm_iproc_i2c_dev *iproc_i2c = data; ++ u32 status = readl(iproc_i2c->base + IS_OFFSET); ++ ++ status &= ISR_MASK; ++ ++ if (!status) ++ return IRQ_NONE; ++ ++ writel(status, iproc_i2c->base + IS_OFFSET); ++ iproc_i2c->xfer_is_done = 1; ++ complete_all(&iproc_i2c->done); ++ ++ return IRQ_HANDLED; ++} ++ ++static int bcm_iproc_i2c_check_status(struct bcm_iproc_i2c_dev *iproc_i2c, ++ struct i2c_msg *msg) ++{ ++ u32 val; ++ ++ val = readl(iproc_i2c->base + M_CMD_OFFSET); ++ val = (val >> M_CMD_STATUS_SHIFT) & M_CMD_STATUS_MASK; ++ ++ switch (val) { ++ case M_CMD_STATUS_SUCCESS: ++ return 0; ++ ++ case M_CMD_STATUS_LOST_ARB: ++ dev_dbg(iproc_i2c->device, "lost bus arbitration\n"); ++ return -EAGAIN; ++ ++ case M_CMD_STATUS_NACK_ADDR: ++ dev_dbg(iproc_i2c->device, "NAK addr:0x%02x\n", msg->addr); ++ return -ENXIO; ++ ++ case M_CMD_STATUS_NACK_DATA: ++ dev_dbg(iproc_i2c->device, "NAK data\n"); ++ return -ENXIO; ++ ++ case M_CMD_STATUS_TIMEOUT: ++ dev_dbg(iproc_i2c->device, "bus timeout\n"); ++ return -ETIMEDOUT; ++ ++ default: ++ dev_dbg(iproc_i2c->device, "unknown error code=%d\n", val); ++ return -EIO; ++ } ++} ++ ++static int bcm_iproc_i2c_xfer_single_msg(struct bcm_iproc_i2c_dev *iproc_i2c, ++ struct i2c_msg *msg) ++{ ++ int ret, i; ++ u8 addr; ++ u32 val; ++ unsigned long time_left = msecs_to_jiffies(I2C_TIMEOUT_MESC); ++ ++ /* check if bus is busy */ ++ if (!!(readl(iproc_i2c->base + M_CMD_OFFSET) & ++ BIT(M_CMD_START_BUSY_SHIFT))) { ++ dev_warn(iproc_i2c->device, "bus is busy\n"); ++ return -EBUSY; ++ } ++ ++ /* format and load slave address into the TX FIFO */ ++ addr = msg->addr << 1 | (msg->flags & I2C_M_RD ? 1 : 0); ++ writel(addr, iproc_i2c->base + M_TX_OFFSET); ++ ++ /* for a write transaction, load data into the TX FIFO */ ++ if (!(msg->flags & I2C_M_RD)) { ++ for (i = 0; i < msg->len; i++) { ++ val = msg->buf[i]; ++ ++ /* mark the last byte */ ++ if (i == msg->len - 1) ++ val |= 1 << M_TX_WR_STATUS_SHIFT; ++ ++ writel(val, iproc_i2c->base + M_TX_OFFSET); ++ } ++ } ++ ++ /* mark as incomplete before starting the transaction */ ++ reinit_completion(&iproc_i2c->done); ++ iproc_i2c->xfer_is_done = 0; ++ ++ /* ++ * Enable the "start busy" interrupt, which will be triggered after the ++ * transaction is done, i.e., the internal start_busy bit, transitions ++ * from 1 to 0. ++ */ ++ writel(1 << IE_M_START_BUSY_SHIFT, iproc_i2c->base + IE_OFFSET); ++ ++ /* ++ * Now we can activate the transfer. For a read operation, specify the ++ * number of bytes to read ++ */ ++ val = 1 << M_CMD_START_BUSY_SHIFT; ++ if (msg->flags & I2C_M_RD) { ++ val |= (M_CMD_PROTOCOL_BLK_RD << M_CMD_PROTOCOL_SHIFT) | ++ (msg->len << M_CMD_RD_CNT_SHIFT); ++ } else { ++ val |= (M_CMD_PROTOCOL_BLK_WR << M_CMD_PROTOCOL_SHIFT); ++ } ++ writel(val, iproc_i2c->base + M_CMD_OFFSET); ++ ++ time_left = wait_for_completion_timeout(&iproc_i2c->done, time_left); ++ ++ /* disable all interrupts */ ++ writel(0, iproc_i2c->base + IE_OFFSET); ++ /* read it back to flush the write */ ++ readl(iproc_i2c->base + IE_OFFSET); ++ ++ /* make sure the interrupt handler isn't running */ ++ synchronize_irq(iproc_i2c->irq); ++ ++ if (!time_left && !iproc_i2c->xfer_is_done) { ++ dev_err(iproc_i2c->device, "transaction timed out\n"); ++ ++ /* flush FIFOs */ ++ val = (1 << M_FIFO_RX_FLUSH_SHIFT) | ++ (1 << M_FIFO_TX_FLUSH_SHIFT); ++ writel(val, iproc_i2c->base + M_FIFO_CTRL_OFFSET); ++ return -ETIMEDOUT; ++ } ++ ++ ret = bcm_iproc_i2c_check_status(iproc_i2c, msg); ++ if (ret) { ++ /* flush both TX/RX FIFOs */ ++ val = (1 << M_FIFO_RX_FLUSH_SHIFT) | ++ (1 << M_FIFO_TX_FLUSH_SHIFT); ++ writel(val, iproc_i2c->base + M_FIFO_CTRL_OFFSET); ++ return ret; ++ } ++ ++ /* ++ * For a read operation, we now need to load the data from FIFO ++ * into the memory buffer ++ */ ++ if (msg->flags & I2C_M_RD) { ++ for (i = 0; i < msg->len; i++) { ++ msg->buf[i] = (readl(iproc_i2c->base + M_RX_OFFSET) >> ++ M_RX_DATA_SHIFT) & M_RX_DATA_MASK; ++ } ++ } ++ ++ return 0; ++} ++ ++static int bcm_iproc_i2c_xfer(struct i2c_adapter *adapter, ++ struct i2c_msg msgs[], int num) ++{ ++ struct bcm_iproc_i2c_dev *iproc_i2c = i2c_get_adapdata(adapter); ++ int ret, i; ++ int xfer_msg_len, xfer_msg_len_max; ++ u8 addr_h, addr_l; ++ ++ /* go through all messages */ ++ for (i = 0; i < num; i++) { ++ xfer_msg_len = msgs[i].len; ++ if (msgs[i].flags & I2C_M_RD) ++ xfer_msg_len_max = I2C_MAX_DATA_READ_LEN; ++ else ++ xfer_msg_len_max = I2C_MAX_DATA_WRITE_LEN; ++ ++ while (xfer_msg_len) { ++ if (xfer_msg_len > xfer_msg_len_max) ++ msgs[i].len = xfer_msg_len_max; ++ ret = bcm_iproc_i2c_xfer_single_msg(iproc_i2c, &msgs[i]); ++ if (ret) { ++ dev_dbg(iproc_i2c->device, "xfer failed\n"); ++ return ret; ++ } ++ ++ if (msgs[i].len == xfer_msg_len_max) { ++ xfer_msg_len -= xfer_msg_len_max; ++ if (xfer_msg_len == 0) ++ break; ++ /* Keep the addr offset for later use */ ++ addr_h = *(msgs[i].buf); ++ addr_l = *(msgs[i].buf + 1); ++ ++ msgs[i].len = xfer_msg_len; ++ msgs[i].buf += xfer_msg_len_max; ++ ++#if defined(CONFIG_ENABLE_WRITE_MSG_SPLIT) ++ if (!(msgs[i].flags & I2C_M_RD)) { ++ /* ++ * For write transfer with len >= 64B, ++ * assuming 2 byte addressing should be ++ * reasonable. ++ */ ++ xfer_msg_len += 2; ++ msgs[i].len = xfer_msg_len; ++ ++ /* ++ * Append new 2-byte address offset. ++ * The upper byte should be unchanged. ++ * The lower byte is increased by ++ * actually written bytes: ++ * (xfer_msg_len_max - 2) ++ */ ++ msgs[i].buf -= 2; ++ *(msgs[i].buf) = addr_h; ++ *(msgs[i].buf + 1) = addr_l - 2 + ++ xfer_msg_len_max; ++ ++ /* ++ * Wait some time so that EEPROM ++ * is ready to respond after previous ++ * partial page write. ++ */ ++ mdelay(10); ++ } ++#endif /* CONFIG_ENABLE_WRITE_MSG_SPLIT */ ++ } else { ++ /* ++ * msgs[i] is transfered completely, ++ * if msgs[i].len is less than xfer_msg_len_max. ++ */ ++ break; ++ } ++ } /* while */ ++ } /* for */ ++ ++ return num; ++} ++ ++ ++static uint32_t bcm_iproc_i2c_functionality(struct i2c_adapter *adap) ++{ ++ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; ++} ++ ++static const struct i2c_algorithm bcm_iproc_algo = { ++ .master_xfer = bcm_iproc_i2c_xfer, ++ .functionality = bcm_iproc_i2c_functionality, ++}; ++ ++/* ++ * Don't limit the max write length for Linux I2C core, if support of ++ * write msg split is enabled. ++ * Read msg split is support, so max_read_len is commented out. ++ */ ++#if !defined(CONFIG_ENABLE_WRITE_MSG_SPLIT) ++static struct i2c_adapter_quirks bcm_iproc_i2c_quirks = { ++ /* need to reserve one byte in the FIFO for the slave address */ ++ //.max_read_len = M_TX_RX_FIFO_SIZE - 1, ++ .max_write_len = M_TX_RX_FIFO_SIZE - 1, ++}; ++#endif ++ ++static int bcm_iproc_i2c_cfg_speed(struct bcm_iproc_i2c_dev *iproc_i2c) ++{ ++ unsigned int bus_speed; ++ u32 val; ++ int ret = of_property_read_u32(iproc_i2c->device->of_node, ++ "clock-frequency", &bus_speed); ++ if (ret < 0) { ++ dev_info(iproc_i2c->device, ++ "unable to interpret clock-frequency DT property\n"); ++ bus_speed = 100000; ++ } ++ ++ if (bus_speed < 100000) { ++ dev_err(iproc_i2c->device, "%d Hz bus speed not supported\n", ++ bus_speed); ++ dev_err(iproc_i2c->device, ++ "valid speeds are 100khz and 400khz\n"); ++ return -EINVAL; ++ } else if (bus_speed < 400000) { ++ bus_speed = 100000; ++ } else { ++ bus_speed = 400000; ++ } ++ ++ iproc_i2c->bus_speed = bus_speed; ++ val = readl(iproc_i2c->base + TIM_CFG_OFFSET); ++ val &= ~(1 << TIM_CFG_MODE_400_SHIFT); ++ val |= (bus_speed == 400000) << TIM_CFG_MODE_400_SHIFT; ++ writel(val, iproc_i2c->base + TIM_CFG_OFFSET); ++ ++ dev_info(iproc_i2c->device, "bus set to %u Hz\n", bus_speed); ++ ++ return 0; ++} ++ ++static int bcm_iproc_i2c_init(struct bcm_iproc_i2c_dev *iproc_i2c) ++{ ++ u32 val; ++ ++ /* put controller in reset */ ++ val = readl(iproc_i2c->base + CFG_OFFSET); ++ val |= 1 << CFG_RESET_SHIFT; ++ val &= ~(1 << CFG_EN_SHIFT); ++ writel(val, iproc_i2c->base + CFG_OFFSET); ++ ++ /* wait 100 usec per spec */ ++ udelay(100); ++ ++ /* bring controller out of reset */ ++ val &= ~(1 << CFG_RESET_SHIFT); ++ writel(val, iproc_i2c->base + CFG_OFFSET); ++ ++ /* flush TX/RX FIFOs and set RX FIFO threshold to zero */ ++ val = (1 << M_FIFO_RX_FLUSH_SHIFT) | (1 << M_FIFO_TX_FLUSH_SHIFT); ++ writel(val, iproc_i2c->base + M_FIFO_CTRL_OFFSET); ++ ++ /* disable all interrupts */ ++ writel(0, iproc_i2c->base + IE_OFFSET); ++ ++ /* clear all pending interrupts */ ++ writel(0xffffffff, iproc_i2c->base + IS_OFFSET); ++ ++ return 0; ++} ++ ++static void bcm_iproc_i2c_enable_disable(struct bcm_iproc_i2c_dev *iproc_i2c, ++ bool enable) ++{ ++ u32 val; ++ ++ val = readl(iproc_i2c->base + CFG_OFFSET); ++ if (enable) ++ val |= BIT(CFG_EN_SHIFT); ++ else ++ val &= ~BIT(CFG_EN_SHIFT); ++ writel(val, iproc_i2c->base + CFG_OFFSET); ++} ++ ++static int bcm_iproc_i2c_probe(struct platform_device *pdev) ++{ ++ int irq, ret = 0; ++ struct bcm_iproc_i2c_dev *iproc_i2c; ++ struct i2c_adapter *adap; ++ struct resource *res; ++ ++ iproc_i2c = devm_kzalloc(&pdev->dev, sizeof(*iproc_i2c), ++ GFP_KERNEL); ++ if (!iproc_i2c) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, iproc_i2c); ++ iproc_i2c->device = &pdev->dev; ++ init_completion(&iproc_i2c->done); ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ iproc_i2c->base = devm_ioremap_resource(iproc_i2c->device, res); ++ if (IS_ERR(iproc_i2c->base)) ++ return PTR_ERR(iproc_i2c->base); ++ ++ ret = bcm_iproc_i2c_init(iproc_i2c); ++ if (ret) ++ return ret; ++ ++ ret = bcm_iproc_i2c_cfg_speed(iproc_i2c); ++ if (ret) ++ return ret; ++ ++ irq = platform_get_irq(pdev, 0); ++ if (irq <= 0) { ++ dev_err(iproc_i2c->device, "no irq resource\n"); ++ return irq; ++ } ++ iproc_i2c->irq = irq; ++ ++ ret = devm_request_irq(iproc_i2c->device, irq, bcm_iproc_i2c_isr, 0, ++ pdev->name, iproc_i2c); ++ if (ret < 0) { ++ dev_err(iproc_i2c->device, "unable to request irq %i\n", irq); ++ return ret; ++ } ++ ++ bcm_iproc_i2c_enable_disable(iproc_i2c, true); ++ ++ adap = &iproc_i2c->adapter; ++ i2c_set_adapdata(adap, iproc_i2c); ++ strlcpy(adap->name, "Broadcom iProc I2C adapter", sizeof(adap->name)); ++ adap->algo = &bcm_iproc_algo; ++#if !defined(CONFIG_ENABLE_WRITE_MSG_SPLIT) ++ adap->quirks = &bcm_iproc_i2c_quirks; ++#endif ++ adap->dev.parent = &pdev->dev; ++ adap->dev.of_node = pdev->dev.of_node; ++ ++ ret = i2c_add_adapter(adap); ++ if (ret) { ++ dev_err(iproc_i2c->device, "failed to add adapter\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int bcm_iproc_i2c_remove(struct platform_device *pdev) ++{ ++ struct bcm_iproc_i2c_dev *iproc_i2c = platform_get_drvdata(pdev); ++ ++ /* make sure there's no pending interrupt when we remove the adapter */ ++ writel(0, iproc_i2c->base + IE_OFFSET); ++ readl(iproc_i2c->base + IE_OFFSET); ++ synchronize_irq(iproc_i2c->irq); ++ ++ i2c_del_adapter(&iproc_i2c->adapter); ++ bcm_iproc_i2c_enable_disable(iproc_i2c, false); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM_SLEEP ++ ++static int bcm_iproc_i2c_suspend(struct device *dev) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct bcm_iproc_i2c_dev *iproc_i2c = platform_get_drvdata(pdev); ++ ++ /* make sure there's no pending interrupt when we go into suspend */ ++ writel(0, iproc_i2c->base + IE_OFFSET); ++ readl(iproc_i2c->base + IE_OFFSET); ++ synchronize_irq(iproc_i2c->irq); ++ ++ /* now disable the controller */ ++ bcm_iproc_i2c_enable_disable(iproc_i2c, false); ++ ++ return 0; ++} ++ ++static int bcm_iproc_i2c_resume(struct device *dev) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct bcm_iproc_i2c_dev *iproc_i2c = platform_get_drvdata(pdev); ++ int ret; ++ u32 val; ++ ++ /* ++ * Power domain could have been shut off completely in system deep ++ * sleep, so re-initialize the block here ++ */ ++ ret = bcm_iproc_i2c_init(iproc_i2c); ++ if (ret) ++ return ret; ++ ++ /* configure to the desired bus speed */ ++ val = readl(iproc_i2c->base + TIM_CFG_OFFSET); ++ val &= ~(1 << TIM_CFG_MODE_400_SHIFT); ++ val |= (iproc_i2c->bus_speed == 400000) << TIM_CFG_MODE_400_SHIFT; ++ writel(val, iproc_i2c->base + TIM_CFG_OFFSET); ++ ++ bcm_iproc_i2c_enable_disable(iproc_i2c, true); ++ ++ return 0; ++} ++ ++static const struct dev_pm_ops bcm_iproc_i2c_pm_ops = { ++ .suspend_late = &bcm_iproc_i2c_suspend, ++ .resume_early = &bcm_iproc_i2c_resume ++}; ++ ++#define BCM_IPROC_I2C_PM_OPS (&bcm_iproc_i2c_pm_ops) ++#else ++#define BCM_IPROC_I2C_PM_OPS NULL ++#endif /* CONFIG_PM_SLEEP */ ++ ++static const struct of_device_id bcm_iproc_i2c_of_match[] = { ++ { .compatible = "brcm,iproc-i2c" }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, bcm_iproc_i2c_of_match); ++ ++static struct platform_driver bcm_iproc_i2c_driver = { ++ .driver = { ++ .name = "bcm-iproc-i2c", ++ .of_match_table = bcm_iproc_i2c_of_match, ++ .pm = BCM_IPROC_I2C_PM_OPS, ++ }, ++ .probe = bcm_iproc_i2c_probe, ++ .remove = bcm_iproc_i2c_remove, ++}; ++module_platform_driver(bcm_iproc_i2c_driver); ++ ++MODULE_AUTHOR("Ray Jui "); ++MODULE_DESCRIPTION("Broadcom iProc I2C Driver"); ++MODULE_LICENSE("GPL v2"); +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/i2c/busses/iproc_smbus.h b/drivers/i2c/busses/iproc_smbus.h +--- a/drivers/i2c/busses/iproc_smbus.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/i2c/busses/iproc_smbus.h 2017-11-09 17:53:33.705215000 +0800 +@@ -0,0 +1,189 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#ifndef __IPROC_SMBUS_H__ ++#define __IPROC_SMBUS_H__ ++ ++#define IPROC_I2C_INVALID_ADDR 0xFF ++ ++#define MAX_PROC_BUF_SIZE 256 ++#define MAX_PROC_NAME_SIZE 15 ++#define PROC_GLOBAL_PARENT_DIR "iproc-i2c" ++#define PROC_ENTRY_DEBUG "iproc-i2c-dbg" ++ ++#define IPROC_SMB_MAX_RETRIES 35 ++ ++#define GETREGFLDVAL(regval, mask, startbit) (((regval) & (mask)) >> (startbit)) ++ ++#define SETREGFLDVAL(regval, fldval, mask, startbit) regval = \ ++ (regval & ~(mask)) | \ ++ ((fldval) << (startbit)) ++ ++/* Enum to specify clock speed. The user will provide it during initialization. ++ * If needed, it can be changed dynamically ++ */ ++typedef enum iproc_smb_clk_freq { ++ I2C_SPEED_100KHz = 0, ++ I2C_SPEED_400KHz = 1, ++ I2C_SPEED_INVALID = 255 ++} smb_clk_freq_t; ++ ++/* This enum will be used to notify the user of status of a data transfer ++ * request ++ */ ++typedef enum iproc_smb_error_code { ++ I2C_NO_ERR = 0, ++ I2C_TIMEOUT_ERR = 1, ++ I2C_INVALID_PARAM_ERR = 2, /* Invalid parameter(s) passed to the driver */ ++ I2C_OPER_IN_PROGRESS = 3, /* The driver API was called before the present ++ transfer was completed */ ++ I2C_OPER_ABORT_ERR = 4, /* Transfer aborted unexpectedly, for example a NACK ++ received, before last byte was read/written */ ++ I2C_FUNC_NOT_SUPPORTED = 5, /* Feature or function not supported ++ (e.g., 10-bit addresses, or clock speeds ++ other than 100KHz, 400KHz) */ ++} iproc_smb_error_code_t; ++ ++/* Counters will be used mainly for testing and debugging */ ++struct iproc_smb_counters { ++ unsigned int num_read_requests; ++ unsigned int num_write_requests; ++ unsigned int num_read_errors; ++ unsigned int num_write_errors; ++ unsigned int mstr_rx_evt_cnt; /* ISR counter to check recv event */ ++ unsigned int mstr_start_busy_cnt; /* ISR counter to checking xact sts */ ++ unsigned int mstr_rx_fifo_full_cnt; /* ISR counter to detect rx fifo full */ ++ unsigned int last_int_sts; /* last value of intr status reg */ ++}; ++ ++ ++/* This enum may be used in a call back function to provide the user of the ++ * type of request sent by the user. It can also be used for testing and ++ * debugging purposes ++ */ ++typedef enum iproc_smb_message_type { ++ I2C_DISABLE_MSG = 0, /* To be used after hardware initialization. ++ Driver will _not_ respond to API calls */ ++ I2C_ENABLE_MSG = 1, /* Used after hardware initialization, if required. ++ Driver will start responding to API calls. ++ Will not (re-)program the hardware. */ ++ I2C_READ_MSG = 2, /* I2C read request from application */ ++ I2C_WRITE_MSG = 3 /* I2C write request from application */ ++} iproc_smb_message_type_t; ++ ++/* For debugging purposes, we will store the information about the last ++ * (latest) transfer request from the client application ++ */ ++struct iproc_smb_dbg_trans_info ++{ ++ iproc_smb_message_type_t i2c_last_mesg_type; ++ unsigned int i2c_last_dev_addr; ++ unsigned int i2c_last_num_bytes_xfer_req; ++}; ++ ++struct procfs { ++ char name[MAX_PROC_NAME_SIZE]; ++ struct proc_dir_entry *parent; ++}; ++ ++/* This structure will be used internally by the driver to maintain its ++ * configuration information as well as information programmed in to the ++ * hardware ++ */ ++struct iproc_smb_drv_int_data { ++ struct device *dev; ++ struct iproc_smb_drv_int_data *next; ++ ++ int irq; ++ ++ unsigned int drv_state_init; /* 1 = Initialized, 0 = not initialized */ ++ ++ unsigned int drv_state_open; /* 1 = Accepting transaction requests, ++ 0 = Not accepting transaction requests */ ++ smb_clk_freq_t clk_speed; ++ ++ void __iomem *block_base_addr; /* iomapped virtual base address for ++ register access */ ++ ++ struct i2c_adapter adapter; ++ ++ unsigned int i2c_slave_addr; /* Up to four 7-bit SMB slave addresses can be ++ assigned, we will assume only one for now. ++ Valid only if SMBus will act as a slave ++ device */ ++ ++ struct semaphore xfer_lock; /* Lock for data transfer */ ++ ++ struct completion ses_done; /* To signal the command completion */ ++ ++ struct procfs proc; ++ ++ volatile int debug; ++ ++ unsigned int master_rx_fifo_thr; /* Master FIFO threshold. Interrupt will be ++ generated if the threshold is exceeded */ ++ ++ unsigned int slave_rx_fifo_thr; /* Slave FIFO threshold. Interrupt will be ++ generated if the threshold is exceeded */ ++ ++ unsigned int enable_evts; /* If true, enable interrupts. If false, ++ disable interrupts. Default is false */ ++ unsigned int evt_enable_bmap; /* Bit map of events enabled by the driver */ ++ ++ struct iproc_smb_counters smb_counters; /* Statistics maintained by driver. A caller ++ can request them through an API */ ++}; ++ ++/* Data to be supplied by the platform to initialise the IPROC SMBus (I2C). ++ * block ++ * init: Function called during driver initialization. Used by platform to ++ * configure GPIO functions and similar. ++ */ ++struct iproc_smb_platform_data { ++ int (*init)(struct iproc_smb_drv_int_data *iproc_i2c_info_ptr, int flags); ++ ++ unsigned int flags; ++}; ++ ++/* This structure will be used by the user during driver initialization to pass ++ * initial configuration information to the driver ++ */ ++struct iproc_smb_init_params { ++ unsigned int intr_mode; /* TRUE (1) for enabling interrupt mode, ++ FALSE (0) for polling mode */ ++ unsigned int clock_freq; /* 0=100KHz, 1=400KHz */ ++ void (*i2c_callback_func)(unsigned char *data); /* Application can ++ register a callback ++ function for driver to ++ notify the application ++ of any asynchronous ++ event(s), or exception. ++ Can be NULL */ ++}; ++ ++/* Structure used to pass information to read/write functions. */ ++struct iproc_xact_info { ++ bool cmd_valid; /* true if command field below is valid. Otherwise, false */ ++ unsigned short command; /* Passed by caller to send SMBus command code */ ++ unsigned char *data; /* actual data pased by the caller */ ++ unsigned int size; /* Size of data buffer passed */ ++ unsigned short flags; /* Sent by caller specifying PEC, 10-bit addresses */ ++ unsigned char smb_proto; /* SMBus protocol to use to perform transaction */ ++}; ++ ++#define XACT_TIMEOUT (msecs_to_jiffies(100)) /* Verify if 100 is OK */ ++ ++#endif /* __IPROC_SMBUS_H__ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/i2c/busses/iproc_smbus_defs.h b/drivers/i2c/busses/iproc_smbus_defs.h +--- a/drivers/i2c/busses/iproc_smbus_defs.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/i2c/busses/iproc_smbus_defs.h 2017-11-09 17:53:33.705243000 +0800 +@@ -0,0 +1,47 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#ifndef __IPROC_SMBUS_DEFS_H__ ++#define __IPROC_SMBUS_DEFS_H__ ++ ++/* Transaction error codes defined in Master command register (0x30) */ ++#define MSTR_STS_XACT_SUCCESS 0 ++#define MSTR_STS_LOST_ARB 1 ++#define MSTR_STS_NACK_FIRST_BYTE 2 ++#define MSTR_STS_NACK_NON_FIRST_BYTE 3 /* NACK on a byte other than ++ the first byte */ ++#define MSTR_STS_TTIMEOUT_EXCEEDED 4 ++#define MSTR_STS_TX_TLOW_MEXT_EXCEEDED 5 ++#define MSTR_STS_RX_TLOW_MEXT_EXCEEDED 6 ++ ++/* SMBUS protocol values defined in register 0x30 */ ++#define SMBUS_PROT_QUICK_CMD 0 ++#define SMBUS_PROT_SEND_BYTE 1 ++#define SMBUS_PROT_RECV_BYTE 2 ++#define SMBUS_PROT_WR_BYTE 3 ++#define SMBUS_PROT_RD_BYTE 4 ++#define SMBUS_PROT_WR_WORD 5 ++#define SMBUS_PROT_RD_WORD 6 ++#define SMBUS_PROT_BLK_WR 7 ++#define SMBUS_PROT_BLK_RD 8 ++#define SMBUS_PROT_PROC_CALL 9 ++#define SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL 10 ++ ++#define BUS_BUSY_COUNT 100000 /* Number can be changed later */ ++ ++#define DISABLE_INTR 0 ++#define ENABLE_INTR 1 ++#endif /* __IPROC_SMBUS_DEFS_H__ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/i2c/busses/iproc_smbus_regs.h b/drivers/i2c/busses/iproc_smbus_regs.h +--- a/drivers/i2c/busses/iproc_smbus_regs.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/i2c/busses/iproc_smbus_regs.h 2017-11-09 17:53:33.706235000 +0800 +@@ -0,0 +1,290 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#ifndef __IPROC_SMBUS_REGS_H__ ++#define __IPROC_SMBUS_REGS_H__ ++ ++/* --- */ ++#define CCB_SMB_CFG_REG 0x0 ++ ++#define CCB_SMB_CFG_RST_MASK 0x80000000 ++#define CCB_SMB_CFG_RST_SHIFT 31 ++ ++#define CCB_SMB_CFG_SMBEN_MASK 0x40000000 ++#define CCB_SMB_CFG_SMBEN_SHIFT 30 ++ ++#define CCB_SMB_CFG_BITBANGEN_MASK 0x20000000 ++#define CCB_SMB_CFG_BITBANGEN_SHIFT 29 ++ ++#define CCB_SMB_CFG_EN_NIC_SMBADDR0_MASK 0x10000000 ++#define CCB_SMB_CFG_EN_NIC_SMBADDR0_SHIFT 28 ++ ++#define CCB_SMB_CFG_PROMISCMODE_MASK 0x08000000 ++#define CCB_SMB_CFG_PROMISCMODE_SHIFT 27 ++ ++#define CCB_SMB_CFG_TSTMPCNTEN_MASK 0x04000000 ++#define CCB_SMB_CFG_TSTMPCNTEN_SHIFT 26 ++ ++#define CCB_SMB_CFG_MSTRRTRYCNT_MASK 0x000F0000 ++#define CCB_SMB_CFG_MSTRRTRYCNT_SHIFT 16 ++ ++ ++/* --- */ ++#define CCB_SMB_TIMGCFG_REG 0x4 ++ ++#define CCB_SMB_TIMGCFG_MODE400_MASK 0x80000000 ++#define CCB_SMB_TIMGCFG_MODE400_SHIFT 31 ++ ++#define CCB_SMB_TIMGCFG_RNDSLVSTR_MASK 0x7F000000 ++#define CCB_SMB_TIMGCFG_RNDSLVSTR_SHIFT 24 ++ ++#define CCB_SMB_TIMGCFG_PERSLVSTR_MASK 0x00FF0000 ++#define CCB_SMB_TIMGCFG_PERSLVSTR_SHIFT 16 ++ ++#define CCB_SMB_TIMGCFG_IDLTIME_MASK 0x0000FF00 ++#define CCB_SMB_TIMGCFG_IDLTIME_SHIFT 8 ++ ++/* --- */ ++#define CCB_SMB_ADDR_REG 0x8 ++ ++#define CCB_SMB_EN_NIC_SMBADDR3_MASK 0x80000000 ++#define CCB_SMB_EN_NIC_SMBADDR3_SHIFT 31 ++ ++#define CCB_SMB_NIC_SMBADDR3_MASK 0x7F000000 ++#define CCB_SMB_NIC_SMBADDR3_SHIFT 24 ++ ++#define CCB_SMB_EN_NIC_SMBADDR2_MASK 0x00800000 ++#define CCB_SMB_EN_NIC_SMBADDR2_SHIFT 23 ++ ++#define CCB_SMB_NIC_SMBADDR2_MASK 0x007F0000 ++#define CCB_SMB_NIC_SMBADDR2_SHIFT 16 ++ ++#define CCB_SMB_EN_NIC_SMBADDR1_MASK 0x00008000 ++#define CCB_SMB_EN_NIC_SMBADDR1_SHIFT 15 ++ ++#define CCB_SMB_NIC_SMBADDR1_MASK 0x00007F00 ++#define CCB_SMB_NIC_SMBADDR1_SHIFT 8 ++ ++#define CCB_SMB_EN_NIC_SMBADDR0_MASK 0x00000080 ++#define CCB_SMB_EN_NIC_SMBADDR0_SHIFT 7 ++ ++#define CCB_SMB_NIC_SMBADDR0_MASK 0x0000007F ++#define CCB_SMB_NIC_SMBADDR0_SHIFT 0 ++ ++/* --- */ ++#define CCB_SMB_MSTRFIFOCTL_REG 0xC ++ ++#define CCB_SMB_MSTRRXFIFOFLSH_MASK 0x80000000 ++#define CCB_SMB_MSTRRXFIFOFLSH_SHIFT 31 ++ ++#define CCB_SMB_MSTRTXFIFOFLSH_MASK 0x40000000 ++#define CCB_SMB_MSTRTXFIFOFLSH_SHIFT 30 ++ ++#define CCB_SMB_MSTRRXPKTCNT_MASK 0x007F0000 ++#define CCB_SMB_MSTRRXPKTCNT_SHIFT 16 ++ ++#define CCB_SMB_MSTRRXFIFOTHR_MASK 0x00003F00 ++#define CCB_SMB_MSTRRXFIFOTHR_SHIFT 8 ++ ++/* --- */ ++#define CCB_SMB_SLVFIFOCTL_REG 0x10 ++ ++#define CCB_SMB_SLVRXFIFOFLSH_MASK 0x80000000 ++#define CCB_SMB_SLVRXFIFOFLSH_SHIFT 31 ++ ++#define CCB_SMB_SLVTXFIFOFLSH_MASK 0x40000000 ++#define CCB_SMB_SLVTXFIFOFLSH_SHIFT 30 ++ ++#define CCB_SMB_SLVRXPKTCNT_MASK 0x007F0000 ++#define CCB_SMB_SLVRXPKTCNT_SHIFT 16 ++ ++#define CCB_SMB_SLVRXFIFOTHR_MASK 0x00003F00 ++#define CCB_SMB_SLVRXFIFOTHR_SHIFT 8 ++ ++/* --- */ ++#define CCB_SMB_BITBANGCTL_REG 0x14 ++ ++#define CCB_SMB_SMBCLKIN_MASK 0x80000000 ++#define CCB_SMB_SMBCLKIN_SHIFT 31 ++ ++#define CCB_SMB_SMBCLKOUTEN_MASK 0x40000000 ++#define CCB_SMB_SMBCLKOUTEN_SHIFT 30 ++ ++#define CCB_SMB_SMBDATAIN_MASK 0x20000000 ++#define CCB_SMB_SMBDATAIN_SHIFT 29 ++ ++#define CCB_SMB_SMBDATAOUTEN_MASK 0x10000000 ++#define CCB_SMB_SMBDATAOUTEN_SHIFT 28 ++ ++/* --- */ ++#define CCB_SMB_MSTRCMD_REG 0x30 ++ ++#define CCB_SMB_MSTRSTARTBUSYCMD_MASK 0x80000000 ++#define CCB_SMB_MSTRSTARTBUSYCMD_SHIFT 31 ++ ++#define CCB_SMB_MSTRABORT_MASK 0x40000000 ++#define CCB_SMB_MSTRABORT_SHIFT 30 ++ ++#define CCB_SMB_MSTRSTS_MASK 0x0E000000 ++#define CCB_SMB_MSTRSTS_SHIFT 25 ++ ++#define CCB_SMB_MSTRSMBUSPROTO_MASK 0x00001E00 ++#define CCB_SMB_MSTRSMBUSPROTO_SHIFT 9 ++ ++#define CCB_SMB_MSTRPEC_MASK 0x00000100 ++#define CCB_SMB_MSTRPEC_SHIFT 8 ++ ++#define CCB_SMB_MSTRRDBYTECNT_MASK 0x000000FF ++#define CCB_SMB_MSTRRDBYTECNT_SHIFT 0 ++ ++/* --- */ ++#define CCB_SMB_SLVCMD_REG 0x34 ++ ++#define CCB_SMB_SLVSTARTBUSYCMD_MASK 0x80000000 ++#define CCB_SMB_SLVSTARTBUSYCMD_SHIFT 31 ++ ++#define CCB_SMB_SLVABORT_MASK 0x40000000 ++#define CCB_SMB_SLVABORT_SHIFT 30 ++ ++#define CCB_SMB_SLVSTS_MASK 0x03800000 ++#define CCB_SMB_SLVSTS_SHIFT 23 ++ ++#define CCB_SMB_SLVPEC_MASK 0x00000100 ++#define CCB_SMB_SLVPEC_SHIFT 8 ++ ++ ++/* --- */ ++#define CCB_SMB_EVTEN_REG 0x38 ++ ++#define CCB_SMB_MSTRRXFIFOFULLEN_MASK 0x80000000 ++#define CCB_SMB_MSTRRXFIFOFULLEN_SHIFT 31 ++ ++#define CCB_SMB_MSTRRXFIFOTHRHITEN_MASK 0x40000000 ++#define CCB_SMB_MSTRRXFIFOTHRHITEN_SHIFT 30 ++ ++#define CCB_SMB_MSTRRXEVTEN_MASK 0x20000000 ++#define CCB_SMB_MSTRRXEVTEN_SHIFT 29 ++ ++#define CCB_SMB_MSTRSTARTBUSYEN_MASK 0x10000000 ++#define CCB_SMB_MSTRSTARTBUSYEN_SHIFT 28 ++ ++#define CCB_SMB_MSTRTXUNDEN_MASK 0x08000000 ++#define CCB_SMB_MSTRTXUNDEN_SHIFT 27 ++ ++ ++#define CCB_SMB_SLVRXFIFOFULLEN_MASK 0x04000000 ++#define CCB_SMB_SLVRXFIFOFULLEN_SHIFT 26 ++ ++#define CCB_SMB_SLVRXFIFOTHRHITEN_MASK 0x02000000 ++#define CCB_SMB_SLVRXFIFOTHRHITEN_SHIFT 25 ++ ++#define CCB_SMB_SLVRXEVTEN_MASK 0x01000000 ++#define CCB_SMB_SLVRXEVTEN_SHIFT 24 ++ ++#define CCB_SMB_SLVSTARTBUSYEN_MASK 0x00800000 ++#define CCB_SMB_SLVSTARTBUSYEN_SHIFT 23 ++ ++#define CCB_SMB_SLVTXUNDEN_MASK 0x00400000 ++#define CCB_SMB_SLVTXUNDEN_SHIFT 22 ++ ++#define CCB_SMB_SLVRDEVTEN_MASK 0x00200000 ++#define CCB_SMB_SLVRDEVTEN_SHIFT 21 ++ ++ ++/* --- */ ++#define CCB_SMB_EVTSTS_REG 0x3C ++ ++#define CCB_SMB_MSTRRXFIFOFULLSTS_MASK 0x80000000 ++#define CCB_SMB_MSTRRXFIFOFULLSTS_SHIFT 31 ++ ++#define CCB_SMB_MSTRRXFIFOTHRHITSTS_MASK 0x40000000 ++#define CCB_SMB_MSTRRXFIFOTHRHITSTS_SHIFT 30 ++ ++#define CCB_SMB_MSTRRXEVTSTS_MASK 0x20000000 ++#define CCB_SMB_MSTRRXEVTSTS_SHIFT 29 ++ ++#define CCB_SMB_MSTRSTARTBUSYSTS_MASK 0x10000000 ++#define CCB_SMB_MSTRSTARTBUSYSTS_SHIFT 28 ++ ++#define CCB_SMB_MSTRTXUNDSTS_MASK 0x08000000 ++#define CCB_SMB_MSTRTXUNDSTS_SHIFT 27 ++ ++ ++#define CCB_SMB_SLVRXFIFOFULLSTS_MASK 0x04000000 ++#define CCB_SMB_SLVRXFIFOFULLSTS_SHIFT 26 ++ ++#define CCB_SMB_SLVRXFIFOTHRHITSTS_MASK 0x02000000 ++#define CCB_SMB_SLVRXFIFOTHRHITSTS_SHIFT 25 ++ ++#define CCB_SMB_SLVRXEVTSTS_MASK 0x01000000 ++#define CCB_SMB_SLVRXEVTSTS_SHIFT 24 ++ ++#define CCB_SMB_SLVSTARTBUSYSTS_MASK 0x00800000 ++#define CCB_SMB_SLVSTARTBUSYSTS_SHIFT 23 ++ ++#define CCB_SMB_SLVTXUNDSTS_MASK 0x00400000 ++#define CCB_SMB_SLVTXUNDSTS_SHIFT 22 ++ ++#define CCB_SMB_SLVRDEVTSTS_MASK 0x00200000 ++#define CCB_SMB_SLVRDEVTSTS_SHIFT 21 ++ ++ ++/* --- */ ++#define CCB_SMB_MSTRDATAWR_REG 0x40 ++ ++#define CCB_SMB_MSTRWRSTS_MASK 0x80000000 ++#define CCB_SMB_MSTRWRSTS_SHIFT 31 ++ ++#define CCB_SMB_MSTRWRDATA_MASK 0x000000FF ++#define CCB_SMB_MSTRWRDATA_SHIFT 0 ++ ++ ++/* --- */ ++#define CCB_SMB_MSTRDATARD_REG 0x44 ++ ++#define CCB_SMB_MSTRRDSTS_MASK 0xC0000000 ++#define CCB_SMB_MSTRRDSTS_SHIFT 30 ++ ++#define CCB_SMB_MSTRRDPECERR_MASK 0x20000000 ++#define CCB_SMB_MSTRRDPECERR_SHIFT 29 ++ ++#define CCB_SMB_MSTRRDDATA_MASK 0x000000FF ++#define CCB_SMB_MSTRRDDATA_SHIFT 0 ++ ++ ++/* --- */ ++#define CCB_SMB_SLVDATAWR_REG 0x48 ++ ++#define CCB_SMB_SLVWRSTS_MASK 0x80000000 ++#define CCB_SMB_SLVWRSTS_SHIFT 31 ++ ++#define CCB_SMB_SLVWRDATA_MASK 0x000000FF ++#define CCB_SMB_SLVWRDATA_SHIFT 0 ++ ++ ++/* --- */ ++#define CCB_SMB_SLVDATARD_REG 0x4C ++ ++#define CCB_SMB_SLVRDSTS_MASK 0xC0000000 ++#define CCB_SMB_SLVRDSTS_SHIFT 30 ++ ++#define CCB_SMB_SLVRDERRSTS_MASK 0x30000000 ++#define CCB_SMB_SLVRDERRSTS_SHIFT 28 ++ ++#define CCB_SMB_SLVRDDATA_MASK 0x000000FF ++#define CCB_SMB_SLVRDDATA_SHIFT 0 ++ ++#endif /* __IPROC_SMBUS_REGS_H__ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/i2c/busses/xgs_iproc_smbus.c b/drivers/i2c/busses/xgs_iproc_smbus.c +--- a/drivers/i2c/busses/xgs_iproc_smbus.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/i2c/busses/xgs_iproc_smbus.c 2017-11-09 17:53:33.709223000 +0800 +@@ -0,0 +1,2014 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "iproc_smbus_regs.h" ++#include "iproc_smbus_defs.h" ++#include "iproc_smbus.h" ++ ++#ifdef CONFIG_OF ++#include ++#include ++#include ++#endif /* CONFIG_OF */ ++ ++#undef IPROC_SMB_DBG ++ ++/* Support I2C devices without length field xfer*/ ++//#define SMB_BLOCK_XFER_VARIANT ++ ++#define SMB_MAX_DATA_SIZE 32 ++#define SMB_BLK_XFER_TEST ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 37) ++#define init_MUTEX(x) sema_init(x,1) ++#endif ++ ++static struct proc_dir_entry *gProcParent=NULL; ++//static int use_svk_version; ++#undef CONFIG_USE_SVK_VERSION ++ ++static int smb_in_intr; ++ ++static struct iproc_smb_drv_int_data *iproc_smbus_list = NULL; ++static int iproc_smbus_block_init(struct iproc_smb_drv_int_data *dev); ++ ++/* Function to read a value from specified register. */ ++static unsigned int iproc_smb_reg_read(unsigned long reg_addr) ++{ ++ unsigned int val; ++ ++ val = ioread32((void *)reg_addr); ++ ++#ifdef IPROC_SMB_DBG ++ if (!smb_in_intr) { ++ printk(KERN_DEBUG "\nRd: addr:0x%08X, val:0x%08X", (unsigned int)reg_addr, val); ++ } ++#endif ++ ++ return(val); ++} ++ ++/* Function to write a value ('val') in to a specified register. */ ++static int iproc_smb_reg_write(unsigned long reg_addr, unsigned int val) ++{ ++ iowrite32(val, (void *)reg_addr); ++ ++#ifdef IPROC_SMB_DBG ++ if (!smb_in_intr) { ++ printk(KERN_DEBUG "\nWr: addr:0x%08X, val:0x%08X", (unsigned int)reg_addr, val); ++ } ++#endif ++ ++ return (0); ++} ++ ++#ifdef IPROC_SMB_DBG ++static int iproc_dump_smb_regs(struct iproc_smb_drv_int_data *dev) ++{ ++ unsigned int regval; ++ unsigned long base_addr = (unsigned long)dev->block_base_addr; ++ ++ printk(KERN_DEBUG "\n----------------------------------------------"); ++ ++ printk(KERN_DEBUG "\nBase addr=0x%08X", (unsigned int)base_addr); ++ ++ printk(KERN_DEBUG "%s: Dumping SMBus registers... ", __func__); ++ ++ regval = iproc_smb_reg_read(base_addr + CCB_SMB_CFG_REG); ++ printk(KERN_DEBUG "\nCCB_SMB_CFG_REG=0x%08X", regval); ++ ++ regval = iproc_smb_reg_read(base_addr + CCB_SMB_TIMGCFG_REG); ++ printk(KERN_DEBUG "\nCCB_SMB_TIMGCFG_REG=0x%08X", regval); ++ ++ regval = iproc_smb_reg_read(base_addr + CCB_SMB_ADDR_REG); ++ printk(KERN_DEBUG "\nCCB_SMB_ADDR_REG=0x%08X", regval); ++ ++ regval = iproc_smb_reg_read(base_addr + CCB_SMB_MSTRFIFOCTL_REG); ++ printk(KERN_DEBUG "\nCCB_SMB_MSTRFIFOCTL_REG=0x%08X", regval); ++ ++ regval = iproc_smb_reg_read(base_addr + CCB_SMB_SLVFIFOCTL_REG); ++ printk(KERN_DEBUG "\nCCB_SMB_SLVFIFOCTL_REG=0x%08X", regval); ++ ++ regval = iproc_smb_reg_read(base_addr + CCB_SMB_BITBANGCTL_REG); ++ printk(KERN_DEBUG "\nCCB_SMB_BITBANGCTL_REG=0x%08X", regval); ++ ++ regval = iproc_smb_reg_read(base_addr + CCB_SMB_MSTRCMD_REG); ++ printk(KERN_DEBUG "\nCCB_SMB_MSTRCMD_REG=0x%08X", regval); ++ ++ regval = iproc_smb_reg_read(base_addr + CCB_SMB_SLVCMD_REG); ++ printk(KERN_DEBUG "\nCCB_SMB_SLVCMD_REG=0x%08X", regval); ++ ++ regval = iproc_smb_reg_read(base_addr + CCB_SMB_EVTEN_REG); ++ printk(KERN_DEBUG "\nCCB_SMB_EVTEN_REG=0x%08X", regval); ++ ++ regval = iproc_smb_reg_read(base_addr + CCB_SMB_EVTSTS_REG); ++ printk(KERN_DEBUG "\nCCB_SMB_EVTSTS_REG=0x%08X", regval); ++ ++ regval = iproc_smb_reg_read(base_addr + CCB_SMB_MSTRDATAWR_REG); ++ printk(KERN_DEBUG "\nCCB_SMB_MSTRDATAWR_REG=0x%08X", regval); ++ ++ regval = iproc_smb_reg_read(base_addr + CCB_SMB_MSTRDATARD_REG); ++ printk(KERN_DEBUG "\nCCB_SMB_MSTRDATARD_REG=0x%08X", regval); ++ ++ regval = iproc_smb_reg_read(base_addr + CCB_SMB_SLVDATAWR_REG); ++ printk(KERN_DEBUG "\nCCB_SMB_SLVDATAWR_REG=0x%08X", regval); ++ ++ regval = iproc_smb_reg_read(base_addr + CCB_SMB_SLVDATARD_REG); ++ printk(KERN_DEBUG "\nCCB_SMB_SLVDATARD_REG=0x%08X", regval); ++ ++ printk(KERN_DEBUG "\n----------------------------------------------\n\n"); ++ ++ return(0); ++} ++#endif /* IPROC_SMB_DBG */ ++ ++static irqreturn_t iproc_smb_isr(int irq, void*devid) ++{ ++ struct iproc_smb_drv_int_data *dev = ++ (struct iproc_smb_drv_int_data *)devid; ++ unsigned int intsts; ++ unsigned int regval; ++ ++ ++ smb_in_intr = 1; ++ ++ intsts = iproc_smb_reg_read((unsigned long)dev->block_base_addr + ++ CCB_SMB_EVTSTS_REG); ++ ++ dev->smb_counters.last_int_sts = intsts; ++ ++ if (!intsts) { ++ ++ /* Likely received a spurious interrupt */ ++ ++ return IRQ_NONE; ++ ++ } ++ ++ /* Clear interrupts */ ++ iproc_smb_reg_write((unsigned long)dev->block_base_addr + ++ CCB_SMB_EVTSTS_REG, intsts); ++ ++ /* Master read or write complete */ ++ if ((intsts & CCB_SMB_MSTRSTARTBUSYEN_MASK) || ++ (intsts & CCB_SMB_MSTRRXEVTSTS_MASK)) { ++ ++ if (intsts & CCB_SMB_MSTRSTARTBUSYEN_MASK) { ++ ++ dev->smb_counters.mstr_start_busy_cnt++; ++ ++ } ++ ++ if (intsts & CCB_SMB_MSTRRXEVTSTS_MASK) { ++ ++ dev->smb_counters.mstr_rx_evt_cnt++; ++ ++ } ++ ++ /* In case of a receive transaction, data will be copied in the recv ++ * function ++ */ ++ complete(&dev->ses_done); ++ ++ } ++ ++ /* If RX FIFO was full we can either read and then flush the FIFO. Or, only ++ * flush the FIFO (since the client process did not read the data on time), ++ * and then the client process can restart the transaction ++ * For now, we will flush the later action. ++ */ ++ if (intsts & CCB_SMB_MSTRRXFIFOFULLSTS_MASK) { ++ ++ dev->smb_counters.mstr_rx_fifo_full_cnt++; ++ ++ regval = iproc_smb_reg_read((unsigned long)dev->block_base_addr + ++ CCB_SMB_MSTRFIFOCTL_REG); ++ ++ regval |= CCB_SMB_MSTRRXFIFOFLSH_MASK; ++ ++ iproc_smb_reg_write((unsigned long)dev->block_base_addr + ++ CCB_SMB_MSTRFIFOCTL_REG, regval); ++ ++ complete(&dev->ses_done); ++ ++ } ++ ++ smb_in_intr = 0; ++ ++ return IRQ_HANDLED; ++} ++ ++/* ++ * Function to ensure that the previous transaction was completed before ++ * initiating a new transaction. It can also be used in polling mode to ++ * check status of completion of a command ++ */ ++static int iproc_smb_startbusy_wait(struct iproc_smb_drv_int_data *dev) ++{ ++ unsigned int regval; ++ ++ regval = iproc_smb_reg_read((unsigned long)dev->block_base_addr + ++ CCB_SMB_MSTRCMD_REG); ++ ++ /* Check if an operation is in progress. During probe it won't be. ++ * But when shutdown/remove was called we want to make sure that ++ * the transaction in progress completed ++ */ ++ if (regval & CCB_SMB_MSTRSTARTBUSYCMD_MASK) { ++ unsigned int i = 0; ++ ++ do { ++ ++ msleep(1); /* Wait for 1 msec */ ++ ++ i++; ++ ++ regval = iproc_smb_reg_read( ++ (unsigned long)dev->block_base_addr + CCB_SMB_MSTRCMD_REG); ++ ++ /* If start-busy bit cleared, exit the loop */ ++ } while ((regval & CCB_SMB_MSTRSTARTBUSYCMD_MASK) && ++ (i < IPROC_SMB_MAX_RETRIES)); ++ ++ if (i >= IPROC_SMB_MAX_RETRIES) { ++ printk(KERN_ERR "%s: %s START_BUSY bit didn't clear, exiting\n", ++ __func__, dev->adapter.name); ++ return -ETIMEDOUT; ++ ++ } ++ ++ } ++ ++ return 0; ++} ++ ++ ++static unsigned int smbus0_sdaRecoveryCnt = 0, smbus0_sdaFailedCnt = 0, smbus0_startBusyCnt = 0; ++static unsigned int smbus1_sdaRecoveryCnt = 0, smbus1_sdaFailedCnt = 0, smbus1_startBusyCnt = 0; ++ ++/* ++ * Function to recover SMB hangs caused stuck master START_BUSY. ++ * Returns 0 if recovery procedure executed successfully. ++ * Returns -1 if recovery failed. ++ */ ++static int iproc_smb_startbusy_recovery(struct iproc_smb_drv_int_data *dev) ++{ ++ int rc = -1; ++ unsigned int recoveryCnt; ++ ++ if (dev->adapter.nr == 0) { ++ recoveryCnt = ++smbus0_startBusyCnt; ++ } ++ else { ++ recoveryCnt = ++smbus1_startBusyCnt; ++ } ++ ++ printk(KERN_INFO "%s: %s START_BUSY recovery #%d \n", __func__, dev->adapter.name, recoveryCnt); ++ ++ /* reset the SMBus block, wait a minimum of 50 uSecs and then re-initialize */ ++ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_CFG_REG, CCB_SMB_CFG_RST_MASK); ++ udelay(60); ++ ++ if ( iproc_smbus_block_init(dev) == 0 ) { ++ rc = 0; ++ } ++ ++ return rc; ++} ++ ++ ++ ++/* ++ * Function to recover SMB hang caused by a slave device holding SDA low. ++ * Returns 0 if recovery procedure executed successfully. ++ * Returns -1 if recovery failed. ++ */ ++ ++static int iproc_smb_sda_low_recovery(struct iproc_smb_drv_int_data *dev) ++{ ++ unsigned int bbReg, cfgReg, cfgSave, recoveryCnt, failedCnt, i; ++ int rc = -1; ++ ++ ++ /* enable bit-bang */ ++ cfgSave = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_CFG_REG); ++ cfgReg = cfgSave; ++ cfgReg |= CCB_SMB_CFG_BITBANGEN_MASK; ++ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_CFG_REG, cfgReg); ++ udelay(50); ++ ++ /* start with clock and SDA set high */ ++ bbReg = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_BITBANGCTL_REG); ++ ++ bbReg |= (CCB_SMB_SMBCLKOUTEN_MASK | CCB_SMB_SMBDATAOUTEN_MASK); ++ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_BITBANGCTL_REG, bbReg); ++ udelay(5); /* should be sufficient for 100 KHz bus */ ++ ++ /* set up to toggle the clock line with SDA out held high for 9 cycles */ ++ for (i=0; i<18; i++) ++ { ++ /* toggle CLK out */ ++ if ( (bbReg & CCB_SMB_SMBCLKOUTEN_MASK) == 0 ) { ++ bbReg |= CCB_SMB_SMBCLKOUTEN_MASK; /* set clock high */ ++ } ++ else { ++ bbReg &= ~CCB_SMB_SMBCLKOUTEN_MASK; /* set clock low */ ++ } ++ ++ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_BITBANGCTL_REG, bbReg); ++ udelay(5); ++ } ++ ++ /* check bit 29 -- SMBDAT_IN and make sure SDA not being held low any more */ ++ for ( i=0; i<10; i++ ) ++ { ++ bbReg = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_BITBANGCTL_REG); ++ bbReg &= CCB_SMB_SMBDATAIN_MASK; ++ ++ if (bbReg) ++ break; ++ ++ udelay(1); ++ } ++ ++ if ( bbReg == 0 ) { ++ /* SDA is still low */ ++ if (dev->adapter.nr == 0) { ++ failedCnt = ++smbus0_sdaFailedCnt; ++ } ++ else { ++ failedCnt = ++smbus1_sdaFailedCnt; ++ } ++ printk(KERN_INFO "\n%s: %s SDA release #%d FAILED.\n", __func__, dev->adapter.name, failedCnt); ++ } ++ else { ++ if (dev->adapter.nr == 0) { ++ recoveryCnt = ++smbus0_sdaRecoveryCnt; ++ } ++ else { ++ recoveryCnt = ++smbus1_sdaRecoveryCnt; ++ } ++ ++ printk(KERN_INFO "%s: %s SDA release #%d SUCCESSFUL.\n", __func__, dev->adapter.name, recoveryCnt); ++ rc = 0; ++ } ++ ++ ++ /* manually issue a stop by transitioning SDA from low to high with clock held high */ ++ bbReg = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_BITBANGCTL_REG); ++ bbReg &= ~CCB_SMB_SMBCLKOUTEN_MASK; /* set clock low */ ++ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_BITBANGCTL_REG, bbReg); ++ udelay(2); ++ ++ bbReg &= ~CCB_SMB_SMBDATAOUTEN_MASK; /* drop SDA low */ ++ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_BITBANGCTL_REG, bbReg); ++ udelay(2); ++ ++ bbReg |= CCB_SMB_SMBCLKOUTEN_MASK; /* set clock high */ ++ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_BITBANGCTL_REG, bbReg); ++ udelay(5); ++ ++ bbReg |= CCB_SMB_SMBDATAOUTEN_MASK; /* pull SDA high */ ++ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_BITBANGCTL_REG, bbReg); ++ udelay(2); ++ ++ ++ /* disable bit-bang and then re-enable the SMB with the saved configuration */ ++ cfgReg = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_CFG_REG); ++ cfgReg &= ~CCB_SMB_CFG_BITBANGEN_MASK; ++ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_CFG_REG, cfgReg); ++ udelay(10); ++ ++ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_CFG_REG, cfgSave); ++ ++ return rc; ++} ++ ++ ++/* ++ * Function to recover SMB hang caused by a slave device hold SDA low. ++ * Returns 0 if recovery procedure executed successfully. ++ * Returns -1 if recovery failed. ++ */ ++static int iproc_smb_timeout_recovery(struct iproc_smb_drv_int_data *dev) ++{ ++ unsigned int bbReg, mCmdReg; ++ int rc = -1; ++ ++ /* read bit-bang control. If SDA low, attempt SDA release recovery */ ++ bbReg = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_BITBANGCTL_REG); ++ ++ if ( (bbReg & CCB_SMB_SMBDATAIN_MASK) == 0 ) { ++ if ( iproc_smb_sda_low_recovery( dev ) == 0 ) { ++ rc = 0; ++ } ++ } ++ ++ /* regardless of whether there was an SDA hang or not, see if START_BUSY stuck high */ ++ mCmdReg = iproc_smb_reg_read( (unsigned long)dev->block_base_addr + CCB_SMB_MSTRCMD_REG ); ++ if ( mCmdReg & CCB_SMB_MSTRSTARTBUSYCMD_MASK ) { ++ /* attempt to recover the bus */ ++ if (iproc_smb_startbusy_recovery(dev) == 0) { ++ rc = 0; ++ } ++ } ++ ++ return rc; ++ ++} ++ ++/* ++ * This function copies data to SMBus's Tx FIFO. Valid for write transactions ++ * only ++ * ++ * base_addr: Mapped address of this SMBus instance ++ * dev_addr: SMBus (I2C) device address. We are assuming 7-bit addresses ++ * initially ++ * info: Data to copy in to Tx FIFO. For read commands, the size should be ++ * set to zero by the caller ++ * ++ */ ++static void iproc_smb_write_trans_data(unsigned long base_addr, ++ unsigned short dev_addr, ++ struct iproc_xact_info *info) ++{ ++ unsigned int regval; ++ unsigned int i; ++ unsigned int num_data_bytes = 0; ++ ++#ifdef IPROC_SMB_DBG ++ printk(KERN_DEBUG "\n%s: dev_addr=0x%X, offset=%u, cmd_valid=%u, size=%u\n", __func__, dev_addr, info->command, info->cmd_valid, info->size); ++#endif /* IPROC_SMB_DBG */ ++ ++ /* Write SMBus device address first */ ++ /* Note, we are assuming 7-bit addresses for now. For 10-bit addresses, ++ * we may have one more write to send the upper 3 bits of 10-bit addr ++ */ ++ iproc_smb_reg_write(base_addr + CCB_SMB_MSTRDATAWR_REG, dev_addr); ++ ++ /* If the protocol needs command code, copy it */ ++ if (info->cmd_valid == true) { ++ iproc_smb_reg_write(base_addr + CCB_SMB_MSTRDATAWR_REG, info->command); ++ } ++ ++ /* Depending on the SMBus protocol, we need to write additional transaction ++ * data in to Tx FIFO. Refer to section 5.5 of SMBus spec for sequence for a ++ * transaction ++ */ ++ switch (info->smb_proto) { ++ ++ case SMBUS_PROT_RECV_BYTE: ++ /* No additional data to be written */ ++ num_data_bytes = 0; ++ break; ++ ++ case SMBUS_PROT_SEND_BYTE: ++ num_data_bytes = info->size; ++ break; ++ ++ case SMBUS_PROT_RD_BYTE: ++ case SMBUS_PROT_RD_WORD: ++ case SMBUS_PROT_BLK_RD: ++ /* Write slave address with R/W~ set (bit #0) */ ++ iproc_smb_reg_write(base_addr + CCB_SMB_MSTRDATAWR_REG, dev_addr | 0x1); ++ num_data_bytes = 0; ++ break; ++ ++ case SMBUS_PROT_WR_BYTE: ++ case SMBUS_PROT_WR_WORD: ++ /* No additional bytes to be written. Data portion is written in the ++ * 'for' loop below ++ */ ++ num_data_bytes = info->size; ++ ++ /* Note for hx4 eeprom (at24c64). the low addr bytes can be passed ++ * in to 1st byte of info->data ++ */ ++ break; ++ ++ case SMBUS_PROT_BLK_WR: ++ /* 3rd byte is byte count */ ++#ifndef SMB_BLOCK_XFER_VARIANT ++ iproc_smb_reg_write(base_addr + CCB_SMB_MSTRDATAWR_REG, info->size); ++#endif ++ num_data_bytes = info->size; ++ break; ++ ++ case SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL: ++ /* Write byte count */ ++ iproc_smb_reg_write(base_addr + CCB_SMB_MSTRDATAWR_REG, info->size); ++ num_data_bytes = info->size; ++ break; ++ ++ default: ++ break; ++ ++ } ++ ++ /* Copy actual data from caller, next. In general, for reads, no data is ++ * copied ++ */ ++ for (i = 0; num_data_bytes; --num_data_bytes, i++) { ++ ++ /* For the last byte, set MASTER_WR_STATUS bit. For block rd/wr process ++ * call, we need to program slave addr after copying data byte(s), so ++ * master status bit is set later, after the loop ++ */ ++ if ((num_data_bytes == 1) && ++ (info->smb_proto != SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL)) { ++ regval = info->data[i] | CCB_SMB_MSTRWRSTS_MASK; ++ } ++ else { ++ regval = info->data[i]; ++ } ++ ++ iproc_smb_reg_write(base_addr + CCB_SMB_MSTRDATAWR_REG, regval); ++ ++ } ++ ++ if (info->smb_proto == SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL) { ++ /* Write device address needed during repeat start condition */ ++ iproc_smb_reg_write(base_addr + CCB_SMB_MSTRDATAWR_REG, ++ CCB_SMB_MSTRWRSTS_MASK | dev_addr | 0x1); ++ } ++ ++ return; ++} ++ ++static int iproc_smb_data_send(struct i2c_adapter *adapter, ++ unsigned short addr, ++ struct iproc_xact_info *info) ++{ ++ int rc; ++ unsigned int regval; ++ struct iproc_smb_drv_int_data *dev = i2c_get_adapdata(adapter); ++ unsigned long time_left; ++ ++ ++ /* Make sure the previous transaction completed */ ++ rc = iproc_smb_startbusy_wait(dev); ++ ++ if (rc < 0) { ++ printk(KERN_ERR "%s: Send: %s bus is busy, attempt recovery \n", __func__, dev->adapter.name); ++ /* attempt to recover the bus */ ++ if (iproc_smb_startbusy_recovery(dev) != 0) { ++ return rc; ++ } ++ } ++ ++ if (dev->enable_evts == ENABLE_INTR) { ++ ++ /* Enable start_busy interrupt */ ++ regval = iproc_smb_reg_read((unsigned long)dev->block_base_addr + ++ CCB_SMB_EVTEN_REG); ++ ++ regval |= CCB_SMB_MSTRSTARTBUSYEN_MASK; ++ ++ iproc_smb_reg_write((unsigned long)dev->block_base_addr + ++ CCB_SMB_EVTEN_REG, regval); ++ ++ /* Mark as incomplete before sending the data */ ++ reinit_completion(&dev->ses_done); ++ ++ } ++ ++ /* Write transaction bytes to Tx FIFO */ ++ iproc_smb_write_trans_data((unsigned long)dev->block_base_addr, addr, info); ++ ++ /* Program master command register (0x30) with protocol type and set ++ * start_busy_command bit to initiate the write transaction ++ */ ++ regval = (info->smb_proto << CCB_SMB_MSTRSMBUSPROTO_SHIFT) | ++ CCB_SMB_MSTRSTARTBUSYCMD_MASK; ++ ++ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_MSTRCMD_REG, regval); ++ if (dev->enable_evts == ENABLE_INTR) { ++ /* ++ * Block waiting for the transaction to finish. When it's finished, ++ * we'll be signaled by an interrupt ++ */ ++ time_left = wait_for_completion_timeout(&dev->ses_done, XACT_TIMEOUT); ++ /* Disable start_busy interrupt */ ++ regval = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_EVTEN_REG); ++ regval &= ~CCB_SMB_MSTRSTARTBUSYEN_MASK; ++ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_EVTEN_REG, regval); ++ ++ if (time_left == 0) { ++ printk (KERN_INFO "%s: Send: %s timeout accessing device x%02x\n", ++ __func__, dev->adapter.name, addr); ++ ++ /* attempt to recover the bus */ ++ rc = iproc_smb_timeout_recovery(dev); ++ if ( rc != 0 ) { ++ return -ETIMEDOUT; ++ } ++ else { ++ return -ECOMM; ++ } ++ } ++ } ++ ++ regval = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_MSTRCMD_REG); ++ ++ /* If start_busy bit cleared, check if there are any errors */ ++ if (!(regval & CCB_SMB_MSTRSTARTBUSYCMD_MASK)) { ++ /* start_busy bit cleared, check master_status field now */ ++ regval &= CCB_SMB_MSTRSTS_MASK; ++ regval >>= CCB_SMB_MSTRSTS_SHIFT; ++ ++ if (regval != MSTR_STS_XACT_SUCCESS) { ++ /* We can flush Tx FIFO here */ ++ printk(KERN_ERR "\n\n%s:Send: %s Error in transaction %d to device x%02x, exiting\n", ++ __func__, dev->adapter.name, regval, addr); ++ ++ return -EREMOTEIO; ++ } ++ } ++ ++ return(0); ++} ++ ++static int iproc_smb_data_recv(struct i2c_adapter *adapter, ++ unsigned short addr, ++ struct iproc_xact_info *info, ++ unsigned int *num_bytes_read) ++{ ++ int rc; ++ unsigned int regval; ++ struct iproc_smb_drv_int_data *dev = i2c_get_adapdata(adapter); ++ unsigned long time_left; ++ ++ /* Make sure the previous transaction completed */ ++ rc = iproc_smb_startbusy_wait(dev); ++ ++ if (rc < 0) { ++ printk(KERN_ERR "%s: Receive: %s bus is busy, attempt recovery \n", __func__, dev->adapter.name); ++ /* attempt to recover the bus */ ++ if (iproc_smb_startbusy_recovery(dev) != 0) { ++ return rc; ++ } ++ } ++ ++ if (dev->enable_evts == ENABLE_INTR) { ++ /* Enable start_busy interrupt */ ++ regval = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_EVTEN_REG); ++ ++ /* Set Rx_event_en bit for notification of reception event */ ++ regval |= (CCB_SMB_MSTRSTARTBUSYEN_MASK); ++ ++ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_EVTEN_REG, regval); ++ ++ /* Mark as incomplete before sending the data */ ++ reinit_completion(&dev->ses_done); ++ } ++ ++ /* Program all transaction bytes into master Tx FIFO */ ++ iproc_smb_write_trans_data((unsigned long)dev->block_base_addr, addr, info); ++ ++ /* Program master command register (0x30) with protocol type and set ++ * start_busy_command bit to initiate the write transaction ++ */ ++ regval = (info->smb_proto << CCB_SMB_MSTRSMBUSPROTO_SHIFT) | ++ CCB_SMB_MSTRSTARTBUSYCMD_MASK | info->size; ++ ++ iproc_smb_reg_write((unsigned long)dev->block_base_addr + ++ CCB_SMB_MSTRCMD_REG, regval); ++ ++ if (dev->enable_evts == ENABLE_INTR) { ++ /* ++ * Block waiting for the transaction to finish. When it's finished, ++ * we'll be signaled by an interrupt ++ */ ++ time_left = wait_for_completion_timeout(&dev->ses_done, XACT_TIMEOUT); ++ ++ /* Disable start_busy and rx_event interrupts. Above call has handled ++ * the interrupt ++ */ ++ regval = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_EVTEN_REG); ++ regval &= ~(CCB_SMB_MSTRSTARTBUSYEN_MASK); ++ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_EVTEN_REG, regval); ++ ++ if (time_left == 0) { ++ printk (KERN_ERR "\n%s: Receive: %s timeout accessing device 0x%02x\n", ++ __func__, dev->adapter.name, addr); ++ /* attempt to recover the bus */ ++ rc = iproc_smb_timeout_recovery(dev); ++ if ( rc != 0 ) { ++ return -ETIMEDOUT; ++ } ++ else { ++ return -ECOMM; ++ } ++ } ++ } ++ ++ regval = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_MSTRCMD_REG); ++ ++ /* If start_busy bit cleared, check if there are any errors */ ++ if (!(regval & CCB_SMB_MSTRSTARTBUSYCMD_MASK)) { ++ /* start_busy bit cleared, check master_status field now */ ++ regval &= CCB_SMB_MSTRSTS_MASK; ++ regval >>= CCB_SMB_MSTRSTS_SHIFT; ++ ++ if (regval != MSTR_STS_XACT_SUCCESS) { ++ /* We can flush Tx FIFO here */ ++ printk(KERN_INFO "\n%s: %s Error in transaction %d to device x%02x, exiting\n", ++ __func__, dev->adapter.name, regval, addr); ++ return -EREMOTEIO; ++ } ++ } ++ ++ /* In the isr we will read the received byte, and also deal with ++ * rx fifo full event. The above check is for timeout error. If needed ++ * we may move it to rx isr ++ */ ++ ++ /* For block read, protocol (hw) returns byte count, as the first byte */ ++ if ((info->smb_proto == SMBUS_PROT_BLK_RD) || (info->smb_proto == SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL)) { ++ int i, adj; ++#ifndef SMB_BLOCK_XFER_VARIANT ++ /* Read received byte(s) */ ++ regval = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_MSTRDATARD_REG); ++ *num_bytes_read = regval & CCB_SMB_MSTRRDDATA_MASK; ++#else ++ *num_bytes_read = info->size; ++#endif ++ adj = 0; ++ ++ /* Limit to reading a max of 32 bytes only; just a safeguard. If ++ * # bytes read is a number > 32, check transaction set up, and contact ++ * hw engg. Assumption: PEC is disabled ++ */ ++ /* SMBUS spec ver. 3 (2015) extends max block transfer byte count from 32 to 256 */ ++ /* Use SMB_MAX_DATA_SIZE (according to HW FIFO) instead of I2C_SMBUS_BLOCK_MAX (defined in Linux)*/ ++ /* Current SMBUS HW FIFO length is 64B. For block write xfer, the first three FIFO entries are for slave adress, register ofset, and length count*/ ++ //for (i = 0; (i < *num_bytes_read) && (i < (I2C_SMBUS_BLOCK_MAX - adj)); i++) { ++ for (i = 0; (i < *num_bytes_read) && (i < (SMB_MAX_DATA_SIZE - adj)); i++) { ++ /* Read Rx FIFO for data bytes */ ++ regval = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_MSTRDATARD_REG); ++ info->data[i + adj] = regval & CCB_SMB_MSTRRDDATA_MASK; ++ } ++ /* To make sure that atmost 32 bytes are read */ ++ *num_bytes_read = i + adj; ++ } ++ else { ++ regval = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_MSTRDATARD_REG); ++ *info->data = regval & CCB_SMB_MSTRRDDATA_MASK; ++ *num_bytes_read = 1; ++ if (info->smb_proto == SMBUS_PROT_RD_WORD) { ++ /* Read Rx FIFO for data bytes */ ++ regval = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_MSTRDATARD_REG); ++ info->data[1] = regval & CCB_SMB_MSTRRDDATA_MASK; ++ *num_bytes_read = 2; ++ } ++ } ++ ++ return(0); ++} ++ ++static int iproc_smb_xfer(struct i2c_adapter *i2c_adap, u16 addr, ++ unsigned short flags, char read_write, ++ u8 command, int size, union i2c_smbus_data *data) ++{ ++ int rc = 0; ++ struct iproc_smb_drv_int_data *dev = i2c_get_adapdata(i2c_adap); ++ struct iproc_xact_info info; ++ unsigned int num_bytes_read = 0; ++ int smb_xfer_size; ++ ++#ifdef IPROC_SMB_DBG ++ printk(KERN_DEBUG "\n%s: dev=0x%08X\n", __func__, (unsigned int)dev); ++#endif ++ ++ down(&dev->xfer_lock); ++ ++ addr <<= 1; ++ ++ switch (size /* protocol */) { ++ ++ case I2C_SMBUS_BYTE: ++ info.cmd_valid = false; ++ info.command = command; /* not used */ ++ if (read_write == I2C_SMBUS_WRITE) { ++ info.data = &command; ++ } ++ else { ++ info.data = &data->byte; ++ } ++ info.size = 1; ++ info.flags = flags; ++ if (read_write == I2C_SMBUS_READ) { ++ addr |= 0x1; /* Read operation */ ++ info.smb_proto = SMBUS_PROT_RECV_BYTE; ++ info.data = &data->byte; ++ } ++ else { ++ info.smb_proto = SMBUS_PROT_SEND_BYTE; ++ } ++ break; ++ ++ case I2C_SMBUS_BYTE_DATA: ++ info.cmd_valid = true; ++ info.command = command; ++ info.data = &data->byte; ++ info.size = 1; ++ info.flags = flags; ++ ++ if (read_write == I2C_SMBUS_READ) { ++ info.smb_proto = SMBUS_PROT_RD_BYTE; ++ } ++ else { ++ info.smb_proto = SMBUS_PROT_WR_BYTE; ++ //info.smb_proto = SMBUS_PROT_WR_WORD; /* TEMP chg. remove later */ ++ } ++ break; ++ ++ case I2C_SMBUS_WORD_DATA: ++ info.cmd_valid = true; ++ info.command = command; ++ info.data = (unsigned char *)(&data->word); ++ info.size = 2; ++ info.flags = flags; ++ if (read_write == I2C_SMBUS_READ) { ++ info.smb_proto = SMBUS_PROT_RD_WORD; ++ /* Protocol(hw) returns data byte count as part of response, ++ for smbus compliant devices */ ++ // info.size = 0; ++ } ++ else { ++ info.smb_proto = SMBUS_PROT_WR_WORD; ++ info.size = 2; ++ } ++ break; ++ ++ case I2C_SMBUS_BLOCK_DATA: ++ case I2C_SMBUS_I2C_BLOCK_DATA: ++ info.cmd_valid = true; ++ info.command = command; ++ info.data = &data->block[1]; ++ info.flags = flags; ++ ++ if (read_write == I2C_SMBUS_READ) { ++ info.smb_proto = SMBUS_PROT_BLK_RD; ++ /* See desc for RD_BYTE_COUNT in reg 0x30 about 'block read'. ++ * If '0', protocol(hw) returns data byte count as part of ++ * response. ++ */ ++#ifdef SMB_BLOCK_XFER_VARIANT ++ info.size = data->block[0]; ++#else ++ info.size = 0; ++#endif ++ } ++ else { ++ info.smb_proto = SMBUS_PROT_BLK_WR; ++ info.size = data->block[0]; /* i2c-core passes the length in this field */ ++ } ++ ++ break; ++ ++ case I2C_SMBUS_BLOCK_PROC_CALL: ++ info.cmd_valid = true; ++ info.command = command; ++ info.data = &data->block[1]; ++ info.flags = flags; ++ info.size = data->block[0]; ++ info.smb_proto = SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL; ++ break; ++ ++ default: ++ printk(KERN_ERR "%s: Unsupported transaction %d\n", __func__, size); ++ up(&dev->xfer_lock); ++ return -EINVAL; ++ ++ } ++ ++ /* Handle of large packet by spliting into SMB_MAX_DATA_SIZE packet */ ++ smb_xfer_size = (int)info.size; ++ if ((info.smb_proto == SMBUS_PROT_BLK_RD) || (info.smb_proto == SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL)) ++ data->block[0] = 0; ++ while ( smb_xfer_size ) { ++ if (info.size >= SMB_MAX_DATA_SIZE) ++ info.size = SMB_MAX_DATA_SIZE; ++ ++ if (read_write == I2C_SMBUS_READ) { ++ /* Refer to i2c_smbus_read_byte for params passed. */ ++ rc = iproc_smb_data_recv(i2c_adap, addr, &info, &num_bytes_read); ++ /* if failed due to bus hang, but recovered, retry once */ ++ if (rc == -ECOMM) { ++ rc = iproc_smb_data_recv(i2c_adap, addr, &info, &num_bytes_read); ++ } ++ /* For block read call, we pass the actual amount of data sent by ++ * slave, as expected by std Linux API */ ++ if ((info.smb_proto == SMBUS_PROT_BLK_RD) || ++ (info.smb_proto == SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL)) { ++ if (rc == 0) { ++ data->block[0] += num_bytes_read; ++#ifdef IPROC_SMB_DBG ++ printk(KERN_DEBUG "%s: num bytes read=%u\n", ++ __func__, data->block[0]); ++#endif ++ } ++ } ++ } ++ else { ++ /* Refer to i2c_smbus_write_byte params passed. */ ++ rc = iproc_smb_data_send(i2c_adap, addr, &info); ++ /* if failed due to bus hang, but recovered, retry */ ++ if (rc == -ECOMM) { ++ rc = iproc_smb_data_send(i2c_adap, addr, &info); ++ } ++ } ++ ++ if (rc < 0) { ++ printk(KERN_INFO "%s %s: %s error accessing device 0x%X rc=%d", __func__, dev->adapter.name, ++ (read_write == I2C_SMBUS_READ) ? "Read" : "Write", addr, rc); ++ up(&dev->xfer_lock); ++ return -EREMOTEIO; ++ } ++ if (info.size == SMB_MAX_DATA_SIZE) { ++ smb_xfer_size -= SMB_MAX_DATA_SIZE; ++ info.size = smb_xfer_size; ++ info.data += SMB_MAX_DATA_SIZE; ++ info.command += SMB_MAX_DATA_SIZE; /* Adjust I2c device register offset. Not required if the access register addr pointing to FIFO */ ++ } ++ else ++ break; ++ } ++ msleep(1); ++ up(&dev->xfer_lock); ++ ++ return (rc); ++} ++ ++static int ++proc_debug_read(struct file *file, char __user *buffer, size_t count, loff_t *off) ++{ ++ unsigned int len = 0; ++ struct iproc_smb_drv_int_data *dev = (struct iproc_smb_drv_int_data *) PDE_DATA (file->f_inode); ++ ++ if (off > 0) ++ return 0; ++ ++ len += sprintf(buffer + len, "Debug print is %s\n", ++ dev->debug ? "enabled" : "disabled"); ++ ++ return len; ++} ++ ++/* Command interface for reading/writing to various I2C/SMBus devices */ ++#ifndef SMB_BLK_XFER_TEST ++static int ++proc_debug_write(struct file *file, const char __user *buffer, ++ unsigned long count, void *data) ++{ ++ struct iproc_smb_drv_int_data *dev = (struct iproc_smb_drv_int_data *)data; ++ int rc; ++ unsigned char kbuf[MAX_PROC_BUF_SIZE]; ++ union i2c_smbus_data i2cdata; ++ unsigned int val, i2cdev_addr, rd_wr_op; ++ int addr; ++ ++ if (count > MAX_PROC_BUF_SIZE) { ++ count = MAX_PROC_BUF_SIZE; ++ } ++ ++ rc = copy_from_user(kbuf, buffer, count); ++ if (rc) { ++ printk(KERN_ERR "%s: copy_from_user failed status=%d\n", __func__, rc); ++ return -EFAULT; ++ } ++ ++ rc = sscanf(kbuf, "%u %u %d %u", &rd_wr_op, &i2cdev_addr, &addr, &val); ++ if (rc != 4) { ++ printk(KERN_ERR "\necho args > %s", PROC_ENTRY_DEBUG); ++ printk(KERN_ERR "\nargs (all values should be in decimal)):"); ++ printk(KERN_ERR "\nrd_wr_op: 1 = read, 0 = write"); ++ printk(KERN_ERR "\ni2cdev_addr: I2C device address in decimal"); ++ printk(KERN_ERR "\noffset: offset of location within I2C device"); ++ printk(KERN_ERR "\naddr -1 if offset not applicable"); ++ printk(KERN_ERR "\nval: For write op: 8-bit value.\n" ++ " For read op: not used, may be 0\n\n"); ++ return count; ++ } ++ ++ printk("\nArg values :"); ++ printk("\nrd_wr_op = %u", rd_wr_op); ++ printk("\ni2cdev_addr = 0x%X", i2cdev_addr); ++ printk("\noffset = %d", addr); ++ printk("\nval = %u", val); ++ if (rd_wr_op > 1) { ++ printk(KERN_ERR "Error: Invalid rd_wr_op value %u\n", rd_wr_op); ++ return count; ++ } ++ ++ if (i2cdev_addr > 127) { ++ printk(KERN_ERR "Error: i2cdev_addr must be 7-bit value\n"); ++ return count; ++ } ++ ++ if (addr > 255) { ++ printk(KERN_ERR "Error: offset out of range for this device\n"); ++ return count; ++ } ++ ++ printk("Command can execute slow, please wait...\n"); ++ ++ if (rd_wr_op == 0) { /* Write operation */ ++ i2cdata.byte = val; ++ if (addr == -1) { ++ /* Device does not support, or require an offset to write to the ++ * location ++ */ ++ rc = iproc_smb_xfer(&dev->adapter, i2cdev_addr, 0x0, ++ I2C_SMBUS_WRITE, (unsigned char)0, ++ I2C_SMBUS_BYTE, &i2cdata); ++ } else { ++ /* Address required for write access */ ++ rc = iproc_smb_xfer(&dev->adapter, i2cdev_addr, 0x0, ++ I2C_SMBUS_WRITE, addr, I2C_SMBUS_BYTE_DATA, ++ &i2cdata); ++ } ++ ++ if (rc) { ++ printk(KERN_ERR "%s: iproc_smb_xfer:write failed status=%d," ++ " addr=%u, val = 0x%X\n", __func__, rc, addr, val); ++ /* return -EFAULT; */ ++ } else { ++ printk("Write OK.Wrote 0x%X at addr %u\n", val, addr); ++ } ++ ++ msleep(1); /* Delay required, since smb(i2c) interface is slow */ ++ } ++ ++ if (rd_wr_op == 1) { /* Read operation */ ++ if (addr == -1) { ++ /* Device does not support, or require an offset to read from the ++ * location ++ */ ++ rc = iproc_smb_xfer(&dev->adapter, i2cdev_addr, 0x0, I2C_SMBUS_READ, ++ (unsigned char)0, I2C_SMBUS_BYTE, &i2cdata); ++ } else { ++ rc = iproc_smb_xfer(&dev->adapter, i2cdev_addr, 0x0, I2C_SMBUS_READ, ++ addr, I2C_SMBUS_BYTE_DATA, &i2cdata); ++ } ++ ++ if (rc) { ++ printk(KERN_ERR "%s: iproc_smb_xfer failed status=%d\n", __func__, rc); ++ /* return -EFAULT; */ ++ } else { ++ printk("Read OK.Value read at %u = 0x%X\n", addr, i2cdata.byte); ++ } ++ msleep(1); /* Delay required, since smb(i2c) interface is slow */ ++ } ++ ++#ifdef IPROC_SMB_DBG ++ iproc_dump_smb_regs(dev); ++#endif /* IPROC_SMB_DBG */ ++ ++ printk("Last intr sts = 0x%08X\n", dev->smb_counters.last_int_sts); ++ printk("mstr_start_busy_cnt = %u, mstr_rx_evt_cnt = %u, rx fifo full cnt = %u\n\n", ++ dev->smb_counters.mstr_start_busy_cnt, ++ dev->smb_counters.mstr_rx_evt_cnt, ++ dev->smb_counters.mstr_rx_fifo_full_cnt); ++ ++ return count; ++} ++#endif ++ ++#ifdef SMB_BLK_XFER_TEST ++static int ++proc_debug_write(struct file *file, const char __user *buffer, size_t count, loff_t *off) ++{ ++ struct iproc_smb_drv_int_data *dev = (struct iproc_smb_drv_int_data *) PDE_DATA (file->f_inode); ++ int rc; ++ unsigned char kbuf[MAX_PROC_BUF_SIZE]; ++ union i2c_smbus_data i2cdata; ++ unsigned int val, i2cdev_addr, rd_wr_op; ++ int addr; ++ int i, j; ++ unsigned int burst_len, repated_cnt, total_cnt; ++ ++ if (count > MAX_PROC_BUF_SIZE) { ++ count = MAX_PROC_BUF_SIZE; ++ } ++ ++ rc = copy_from_user(kbuf, buffer, count); ++ ++ if (rc) { ++ printk (KERN_ERR "%s: copy_from_user failed status=%d", __func__, rc); ++ return -EFAULT; ++ ++ } ++ ++ rc = sscanf(kbuf, "%u %u %d %u %u %u", &rd_wr_op, &i2cdev_addr, &addr, &val, &burst_len, &repated_cnt); ++ if (rc != 6) { ++ burst_len = 1; ++ repated_cnt = 1; ++ ++ if (rc < 4 ) { ++ printk(KERN_ERR "\necho args > %s", PROC_ENTRY_DEBUG); ++ printk(KERN_ERR "\nargs (all values should be in decimal)):"); ++ printk(KERN_ERR "\nrd_wr_op: 1 = read, 0 = write"); ++ printk(KERN_ERR "\ni2cdev_addr: I2C device address in decimal"); ++ printk(KERN_ERR "\noffset: offset of location within I2C device"); ++ printk(KERN_ERR "\naddr -1 if offset not applicable"); ++ printk(KERN_ERR "\nval: For write op: 8-bit value.\n" ++ " For read op: not used, may be 0\n\n"); ++ printk(KERN_ERR "\burst_length: write block transfer byte length (<=8 for many EEPROM devices)"); ++ printk(KERN_ERR "\repated_cnt: number of repated write transfer of burst_len"); ++ return -EFAULT; ++ } ++ } ++ total_cnt = burst_len * repated_cnt; ++ ++ printk(KERN_DEBUG "\nArg values :"); ++ printk(KERN_DEBUG "\nrd_wr_op = %u", rd_wr_op); ++ printk(KERN_DEBUG "\ni2cdev_addr = 0x%X", i2cdev_addr); ++ printk(KERN_DEBUG "\noffset = %d", addr); ++ printk(KERN_DEBUG "\nval = %u", val); ++ ++ if (rd_wr_op > 1) { ++ printk(KERN_ERR "\nError: Invalid rd_wr_op value %u\n", rd_wr_op); ++ return count; ++ } ++ ++ if (i2cdev_addr > 127) { ++ printk(KERN_ERR "\nError: i2cdev_addr must be 7-bit value\n"); ++ return count; ++ } ++ ++ if (addr > 255) { ++ printk(KERN_ERR "\nError: offset out of range for this device\n"); ++ return count; ++ } ++ ++ printk (KERN_ERR "\nCommand can execute slow, please wait...\n"); ++ ++ if (rd_wr_op == 0) { /* Write operation */ ++ if (total_cnt == 1) { ++#if defined(CONFIG_MACH_SB2) ++ /* Testing EEPROM that requires 2-byte address */ ++ unsigned char *data = &i2cdata.word; ++ data[0] = addr; ++ data[1] = val; ++ rc = iproc_smb_xfer(&dev->adapter, i2cdev_addr, 0x0, ++ I2C_SMBUS_WRITE, (unsigned char)0, I2C_SMBUS_WORD_DATA, &i2cdata); ++#else ++ i2cdata.byte = val; ++ if (addr == -1) { ++ /* Device does not support, or require an offset to write to the ++ * location ++ */ ++ rc = iproc_smb_xfer(&dev->adapter, i2cdev_addr, 0x0, ++ I2C_SMBUS_WRITE, (unsigned char)0, ++ I2C_SMBUS_BYTE, &i2cdata); ++ } ++ else { ++ /* Address required for write access */ ++ rc = iproc_smb_xfer(&dev->adapter, i2cdev_addr, 0x0, ++ I2C_SMBUS_WRITE, addr, I2C_SMBUS_BYTE_DATA, &i2cdata); ++ } ++#endif ++ if (rc) { ++ printk (KERN_ERR "\n%s: iproc_smb_xfer:write failed status=%d," ++ " addr=%u, val = 0x%X\n", __func__, rc, addr, val); ++ /* return -EFAULT; */ ++ } ++ else { ++ printk(KERN_ERR "Write OK. Wrote 0x%X at addr %u\n", val, addr); ++ } ++ msleep(1); /* Delay required, since smb(i2c) interface is slow */ ++ } ++ else { ++/* test of block xfer: echo "0 80 0 0 8 16" > /proc/iproc-i2c/iproc-i2c0/iproc-i2c-dbg */ ++/* write to EEPROM I2c device (slave addr 80=0x50), addr offset: 0, vlaue: starting from 0, block xfer size:8, repeat_cnt:16 (EEPROM doesn't accept block xfer length > 8) */ ++/* repeat_cnt times of write block transfer */ ++/* for single address cycle I2C device only */ ++ for(j=0;jadapter, i2cdev_addr, 0x0, I2C_SMBUS_WRITE, ++ addr+j*burst_len, I2C_SMBUS_BLOCK_DATA, &i2cdata); ++ if (rc) { ++ printk (KERN_ERR "\n%s: iproc_smb_xfer:write failed status=%d," ++ " addr=%u, val = 0x%X\n", __func__, rc, addr, val); ++ return -EFAULT; ++ } ++ msleep(1); ++ } ++ } /* ! total_cnt == 1 */ ++ } ++ ++ if (rd_wr_op == 1) { /* Read operation */ ++ if (total_cnt == 1) { ++#if defined(CONFIG_MACH_SB2) ++ /* Testing EEPROM that requires 2-byte address: to support random read, ++ * issue dummy write and then current address read ++ */ ++ i2cdata.byte = addr; ++ rc = iproc_smb_xfer(&dev->adapter, i2cdev_addr, 0x0, ++ I2C_SMBUS_WRITE, 0, I2C_SMBUS_BYTE_DATA, &i2cdata); ++ if (rc) { ++ printk (KERN_ERR "\n%s: iproc_smb_xfer dummy write failed status=%d\n", __func__, rc); ++ } ++ rc = iproc_smb_xfer(&dev->adapter, i2cdev_addr, 0x0, I2C_SMBUS_READ, ++ (unsigned char)0, I2C_SMBUS_BYTE, &i2cdata); ++#else ++ if (addr == -1) { ++ /* Device does not support, or require an offset to read from the ++ * location ++ */ ++ rc = iproc_smb_xfer(&dev->adapter, i2cdev_addr, 0x0, I2C_SMBUS_READ, ++ (unsigned char)0, I2C_SMBUS_BYTE, &i2cdata); ++ } ++ else { ++ rc = iproc_smb_xfer(&dev->adapter, i2cdev_addr, 0x0, I2C_SMBUS_READ, ++ addr, I2C_SMBUS_BYTE_DATA, &i2cdata); ++ } ++#endif ++ if (rc) { ++ printk (KERN_ERR "\n%s: iproc_smb_xfer failed status=%d\n", __func__, rc); ++ ++ /* return -EFAULT; */ ++ } ++ else { ++ printk(KERN_ERR "\nRead OK.\n--------Value read at %u = 0x%X\n", addr, i2cdata.byte); ++ } ++ ++ msleep(1); /* Delay required, since smb(i2c) interface is slow */ ++ } ++ else { ++ for (i = 1; i <= total_cnt; i++) ++ i2cdata.block[i] = 0; ++ i2cdata.block[0] = total_cnt; ++ rc = iproc_smb_xfer(&dev->adapter, i2cdev_addr, 0x0, I2C_SMBUS_READ, ++ addr, I2C_SMBUS_BLOCK_DATA, &i2cdata); ++ if (rc) { ++ printk (KERN_ERR "\n%s: iproc_smb_xfer:read failed status=%d," ++ " addr=%u, val = 0x%X\n", __func__, rc, addr, val); ++ return -EFAULT; ++ } ++ msleep(1); ++ for (i = 1; i <= total_cnt; i++) ++ printk("%d ", i2cdata.block[i]); ++ } /* ! total_cnt == 1 */ ++ } ++ ++#ifdef IPROC_SMB_DBG ++ iproc_dump_smb_regs(dev); ++#endif ++ ++ printk(KERN_DEBUG "Last intr sts = 0x%08X\n", dev->smb_counters.last_int_sts); ++ ++ printk(KERN_DEBUG "mstr_start_busy_cnt = %u, mstr_rx_evt_cnt = %u, rx fifo full cnt = %u\n", ++ dev->smb_counters.mstr_start_busy_cnt, ++ dev->smb_counters.mstr_rx_evt_cnt, ++ dev->smb_counters.mstr_rx_fifo_full_cnt); ++ ++ return count; ++} ++#endif ++ ++ ++#ifdef CONFIG_USE_SVK_VERSION ++/* Written for SVK boards */ ++static int ++proc_debug_write_svk(struct file *file, const char __user *buffer, size_t count, loff_t *off) ++{ ++ struct iproc_smb_drv_int_data *dev = (struct iproc_smb_drv_int_data *) PDE_DATA (file->f_inode); ++ int rc; ++ unsigned int debug; ++ unsigned char kbuf[MAX_PROC_BUF_SIZE]; ++ union i2c_smbus_data i2cdata; ++ unsigned int val, addr; ++ ++ if (count > MAX_PROC_BUF_SIZE) { ++ count = MAX_PROC_BUF_SIZE; ++ } ++ ++ rc = copy_from_user(kbuf, buffer, count); ++ if (rc) { ++ printk(KERN_ERR "%s: copy_from_user failed status=%d\n", __func__, rc); ++ return -EFAULT; ++ } ++ ++ if (sscanf(kbuf, "%u", &debug) != 1) { ++ printk(KERN_ERR "%s: echo > %s\n", __func__, PROC_ENTRY_DEBUG); ++ return count; ++ } ++ ++ if (debug) { ++ dev->debug = 1; ++ } else { ++ dev->debug = 0; ++ } ++ ++ printk ("Command can execute slow, please wait...\n"); ++ if (!dev->debug) { ++ val = 0xFF; /* Initial value to write */ ++ for(addr = 0x0; addr < 256; val--, addr++) { ++ i2cdata.byte = val; ++ rc = iproc_smb_xfer(&dev->adapter, 0xA0 >> 1, 0x0, I2C_SMBUS_WRITE, ++ addr, I2C_SMBUS_BYTE_DATA, &i2cdata); ++ if (rc) { ++ printk(KERN_ERR "%s: iproc_smb_xfer:write failed status=%d," ++ " addr=%u, val = 0x%X", __func__, rc, addr, val); ++ } else { ++ printk("Write OK. Wrote 0x%X at addr %u\n", val, addr); ++ } ++ msleep(1); /* Delay required, since smb(i2c) interface is slow */ ++ } ++ } else { ++ int i; ++ ++ /* Note about address expected by AT24C02: To write in correct order ++ * to AT24C02 using block write, refer bottom of page 9 (Write ++ * Operations) of the data sheet regarding internal incrementing of ++ * address. Based on that explanation, we program the addr value below. ++ * Select the 'highest' address in that page (7, 15, 23, and so on) to ++ * write to that page ++ */ ++ addr = debug - 1; ++ val = jiffies % 256; ++ printk("EEPROM page write. Page start addr = %u," ++ " write data: \n", debug - 8); ++ ++ for (i = 1; i <= 8; i++) { ++ i2cdata.block[i] = val % 256; /* Fill a sequence pattern */ ++ val++; ++ printk("byte%d = 0x%02X\n", i, i2cdata.block[i]); ++ } ++ ++ i2cdata.block[0] = 8; ++ rc = iproc_smb_xfer(&dev->adapter, 0xA0 >> 1, 0x0, I2C_SMBUS_WRITE, ++ addr, I2C_SMBUS_BLOCK_DATA, &i2cdata); ++ if (rc) { ++ printk(KERN_ERR "%s: iproc_smb_xfer:write failed status=%d," ++ " addr=%u, val = 0x%X\n", __func__, rc, addr, val); ++ } else { ++ printk("Block Write OK.\n"); ++ } ++ } ++ ++#ifdef IPROC_SMB_DBG ++ iproc_dump_smb_regs(dev); ++#endif /* IPROC_SMB_DBG */ ++ ++ printk("Last intr sts = 0x%08X\n", ++ dev->smb_counters.last_int_sts); ++ printk("mstr_start_busy_cnt = %u, mstr_rx_evt_cnt = %u, rx fifo full cnt = %u\n\n", ++ dev->smb_counters.mstr_start_busy_cnt, ++ dev->smb_counters.mstr_rx_evt_cnt, ++ dev->smb_counters.mstr_rx_fifo_full_cnt); ++ ++ return count; ++} ++ ++ ++/* Written for SVK boards */ ++static int ++proc_debug_read_svk(struct file *file, char __user *buffer, size_t count, loff_t *off) ++{ ++ unsigned int len = 0; ++ struct iproc_smb_drv_int_data *dev = (struct iproc_smb_drv_int_data *) PDE_DATA (file->f_inode); ++ int rc; ++ union i2c_smbus_data i2cdata; ++ unsigned int addr; ++ ++ if (off > 0) { ++ return 0; ++ } ++ ++ len += sprintf(buffer + len, "Read\n"); ++ ++ printk(KERN_ERR "\nCommand can execute slow, please wait...\n"); ++ ++ for(addr = 0x0; addr < 256; addr++) { ++ ++ /* Read operation */ ++ rc = iproc_smb_xfer(&dev->adapter, 0xA0 >> 1, 0x0, I2C_SMBUS_READ, addr, ++ I2C_SMBUS_BYTE_DATA, &i2cdata); ++ ++ if (rc) { ++ printk (KERN_ERR "%s: iproc_smb_xfer failed status=%d", __func__, rc); ++ } ++ else { ++ printk(KERN_DEBUG "Read OK.Value read at %u = 0x%X\n", addr, i2cdata.byte); ++ } ++ ++ msleep(1); ++ } ++ ++#ifdef IPROC_SMB_DBG ++ iproc_dump_smb_regs(dev); ++#endif /* IPROC_SMB_DBG */ ++ ++ printk(KERN_DEBUG "\n\nLast intr sts = 0x%08X", dev->smb_counters.last_int_sts); ++ ++ printk(KERN_DEBUG "mstr_start_busy_cnt = %u, mstr_rx_evt_cnt = %u, rx fifo full cnt = %u\n\n", ++ dev->smb_counters.mstr_start_busy_cnt, ++ dev->smb_counters.mstr_rx_evt_cnt, ++ dev->smb_counters.mstr_rx_fifo_full_cnt); ++ ++ return len; ++} ++#endif /* #ifdef CONFIG_USE_SVK_VERSION */ ++ ++static const struct file_operations proc_smb_file_fops= { ++#ifdef CONFIG_USE_SVK_VERSION ++ .read = proc_debug_read_svk, ++ .write = proc_debug_write_svk, ++#else ++ .read = proc_debug_read, ++ .write = proc_debug_write, ++#endif ++ ++}; ++ ++ ++ ++static int proc_init(struct platform_device *pdev) ++{ ++ int rc; ++ struct iproc_smb_drv_int_data *dev = platform_get_drvdata(pdev); ++ struct procfs *proc = &dev->proc; ++ struct proc_dir_entry *proc_debug; ++ ++ ++ snprintf(proc->name, sizeof(proc->name), "%s%d", PROC_GLOBAL_PARENT_DIR, pdev->id); ++ ++ /* sub directory */ ++ proc->parent = proc_mkdir(proc->name, gProcParent); ++ ++ if (proc->parent == NULL) { ++ return -ENOMEM; ++ } ++ ++ proc_debug = proc_create_data(PROC_ENTRY_DEBUG, 0644, proc->parent, &proc_smb_file_fops, dev); ++ ++ if (proc_debug == NULL) { ++ rc = -ENOMEM; ++ goto err_del_parent; ++ } ++ ++ return 0; ++ ++err_del_parent: ++ remove_proc_entry(proc->name, gProcParent); ++ ++ return rc; ++} ++ ++static int proc_term(struct platform_device *pdev) ++{ ++ struct iproc_smb_drv_int_data *dev = platform_get_drvdata(pdev); ++ struct procfs *proc = &dev->proc; ++ ++ remove_proc_entry(PROC_ENTRY_DEBUG, proc->parent); ++ remove_proc_entry(proc->name, gProcParent); ++ ++ return 0; ++} ++ ++/* ++ * This function set clock frequency for SMBus block. As per hardware ++ * engineering, the clock frequency can be changed dynamically. ++ */ ++static int iproc_smb_set_clk_freq(unsigned long base_addr, ++ smb_clk_freq_t freq) ++{ ++ unsigned int regval; ++ unsigned int val; ++ ++ switch (freq) { ++ ++ case I2C_SPEED_100KHz: ++ val = 0; ++ break; ++ ++ case I2C_SPEED_400KHz: ++ val = 1; ++ break; ++ ++ default: ++ return -EINVAL; ++ break; ++ ++ } ++ ++ regval = iproc_smb_reg_read(base_addr + CCB_SMB_TIMGCFG_REG); ++ ++ SETREGFLDVAL(regval, val, CCB_SMB_TIMGCFG_MODE400_MASK, ++ CCB_SMB_TIMGCFG_MODE400_SHIFT); ++ ++ iproc_smb_reg_write(base_addr + CCB_SMB_TIMGCFG_REG, regval); ++ ++ return(0); ++} ++ ++static int iproc_smbus_block_init(struct iproc_smb_drv_int_data *dev) ++{ ++ ++ unsigned long base_addr = (unsigned long)dev->block_base_addr; ++ unsigned int regval; ++#ifdef CONFIG_OF ++ u32 i2c_clk_freq; ++ struct device_node *dn = dev->dev->of_node; ++#endif ++ ++ /* Flush Tx, Rx FIFOs. Note we are setting the Rx FIFO threshold to 0. ++ * May be OK since we are setting RX_EVENT and RX_FIFO_FULL interrupts ++ */ ++ regval = CCB_SMB_MSTRRXFIFOFLSH_MASK | CCB_SMB_MSTRTXFIFOFLSH_MASK; ++ ++ iproc_smb_reg_write(base_addr + CCB_SMB_MSTRFIFOCTL_REG, regval); ++ ++ /* Enable SMbus block. Note, we are setting MASTER_RETRY_COUNT to zero ++ * since there will be only one master ++ */ ++ regval = CCB_SMB_CFG_SMBEN_MASK; ++ ++ iproc_smb_reg_write(base_addr + CCB_SMB_CFG_REG, regval); ++ ++ /* Wait a minimum of 50 Usec, as per SMB hw doc. But we wait longer */ ++ udelay(100); ++ ++ ++ /* Set default clock frequency */ ++#ifndef CONFIG_OF ++ iproc_smb_set_clk_freq(base_addr, I2C_SPEED_100KHz); ++#else ++ if (of_property_read_u32(dn, "clock-frequency", &i2c_clk_freq)) { ++ i2c_clk_freq = I2C_SPEED_100KHz; /*no property available, use default: 100KHz*/ ++ } ++ iproc_smb_set_clk_freq(base_addr, i2c_clk_freq); ++#endif /* CONFIG_OF */ ++ /* Disable intrs */ ++ regval = 0x0; ++ iproc_smb_reg_write(base_addr + CCB_SMB_EVTEN_REG, regval); ++ ++ /* Clear intrs (W1TC) */ ++ regval = iproc_smb_reg_read(base_addr + CCB_SMB_EVTSTS_REG); ++ ++ iproc_smb_reg_write(base_addr + CCB_SMB_EVTSTS_REG, regval); ++ ++ return(0); ++} ++ ++/* This function enables interrupts */ ++static int iproc_intr_enable(struct iproc_smb_drv_int_data *dev, unsigned int bmap) ++{ ++ unsigned long base_addr = (unsigned long)dev->block_base_addr; ++ unsigned int regval; ++ ++ regval = iproc_smb_reg_read(base_addr + CCB_SMB_EVTEN_REG); ++ ++ regval |= bmap; ++ ++ iproc_smb_reg_write(base_addr + CCB_SMB_EVTEN_REG, regval); ++ ++ /* Store all interrupts enabled so far. Note bmap can have only 'incremental' ++ * set of events ++ */ ++ dev->evt_enable_bmap = regval; ++ ++ return(0); ++} ++ ++/* This function disables interrupts */ ++static int iproc_intr_disable(struct iproc_smb_drv_int_data *dev, unsigned int bmap) ++{ ++ unsigned long base_addr = (unsigned long)dev->block_base_addr; ++ unsigned int regval; ++ ++ regval = iproc_smb_reg_read(base_addr + CCB_SMB_EVTEN_REG); ++ ++ regval &= ~bmap; ++ ++ iproc_smb_reg_write(base_addr + CCB_SMB_EVTEN_REG, regval); ++ ++ dev->evt_enable_bmap = regval; ++ ++ return(0); ++} ++ ++/* Verify this sequence with hw engg */ ++static int iproc_smbus_block_deinit(struct iproc_smb_drv_int_data *dev) ++{ ++ unsigned int regval; ++ int rc; ++ ++ /* Disable all interrupts */ ++ regval = 0x0; ++ ++ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_EVTEN_REG, regval); ++ ++ /* Check if a transaction is in progress */ ++ rc = iproc_smb_startbusy_wait(dev); ++ ++ if (rc < 0) { ++ ++ /* Do not exit the function, since we are most likely shutting down */ ++ printk(KERN_ERR "%s: A transaction is still in progress," ++ "but still continuing ", __func__); ++ ++ } ++ ++ /* Disable SMBus block */ ++ regval = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_CFG_REG); ++ ++ regval &= ~CCB_SMB_CFG_SMBEN_MASK; ++ ++ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_CFG_REG, regval); ++ ++ ++ /* Wait for some time */ ++ udelay(100); ++ ++ /* Put the block under reset. Note the RESET bit in reg 0x0 is ++ * self clearing ++ */ ++ regval = CCB_SMB_CFG_RST_MASK; ++ ++ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_CFG_REG, regval); ++ ++ return(0); ++} ++ ++static u32 iproc_smb_funcs(struct i2c_adapter *adapter) ++{ ++ /* I2C_FUNC_SMBUS_I2C_BLOCK */ ++ return (I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA | ++ I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BLOCK_DATA); ++} ++ ++static struct i2c_algorithm iproc_smb_algorithm = { ++ /* .name = "iproc-smb", */ ++ .smbus_xfer = iproc_smb_xfer, ++ .master_xfer = NULL, ++ .functionality = iproc_smb_funcs, ++}; ++ ++ ++static int iproc_smb_probe(struct platform_device *pdev) ++{ ++ int rc=0, irq; ++ struct iproc_smb_drv_int_data *dev; ++ struct i2c_adapter *adap; ++ struct resource *iomem; ++ struct resource *ioarea; ++#ifdef CONFIG_OF ++ struct device_node *dn = pdev->dev.of_node; ++ u32 smb_bus_id; ++#endif ++ ++#ifdef IPROC_SMB_DBG ++ printk(KERN_DEBUG "\n%s: Entering probe\n", __func__); ++#endif /* IPROC_SMB_DBG */ ++ ++#ifdef CONFIG_OF ++ /* first I2C init */ ++ if (gProcParent == NULL) { ++ gProcParent = proc_mkdir(PROC_GLOBAL_PARENT_DIR, NULL); ++ if (gProcParent == NULL) { ++ printk(KERN_ERR "%s: SMBus driver procfs failed\n", __func__); ++ return -ENOMEM; ++ } ++ iproc_smbus_list = NULL; ++ } ++#endif /* CONFIG_OF */ ++ ++ /* Get register memory resource */ ++ iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ ++ if (!iomem) { ++ printk(KERN_ERR "%s: No mem resource\n", __func__); ++ return -ENODEV; ++ } ++ ++#ifdef IPROC_SMB_DBG ++ printk(KERN_DEBUG "\nGot iomem 0x%p\n", iomem); ++#endif /* IPROC_SMB_DBG */ ++ ++ /* Get the interrupt number */ ++ irq = platform_get_irq(pdev, 0); ++ ++ if (irq == -ENXIO) { ++ printk(KERN_ERR "%s: No irq resource\n", __func__); ++ return -ENODEV; ++ } ++ ++#ifdef IPROC_SMB_DBG ++ printk(KERN_DEBUG "\nGot irqnum %d\n", irq); ++#endif /* IPROC_SMB_DBG */ ++ ++ /* Mark the memory region as used */ ++ ioarea = request_mem_region(iomem->start, resource_size(iomem), ++ pdev->name); ++ if (!ioarea) { ++ printk(KERN_ERR "%s: SMBus region already claimed\n", __func__); ++ return -EBUSY; ++ } ++ ++#ifdef IPROC_SMB_DBG ++ printk(KERN_DEBUG "\nGot ioarea 0x%p\n", ioarea); ++#endif /* IPROC_SMB_DBG */ ++ ++ /* Allocate memory for driver's internal data structure */ ++ dev = kzalloc(sizeof(*dev), GFP_KERNEL); ++ ++ if (!dev) { ++ printk(KERN_ERR "%s: Couldn't allocate memory for driver's internaldb\n", __func__); ++ rc = -ENOMEM; ++ goto err_release_mem_region; ++ } ++ ++#ifdef IPROC_SMB_DBG ++ printk(KERN_DEBUG "\nGot dev 0x%p\n", dev); ++#endif /* IPROC_SMB_DBG */ ++ ++ dev->dev = &pdev->dev; ++ init_MUTEX(&dev->xfer_lock); ++ init_completion(&dev->ses_done); ++ dev->irq = irq; ++ ++ dev->block_base_addr = ioremap(iomem->start, resource_size(iomem)); ++ ++ if (!dev->block_base_addr) { ++ printk(KERN_ERR "%s: ioremap of register space failed\n", __func__); ++ rc = -ENOMEM; ++ goto err_free_dev_mem; ++ } ++ ++#ifdef IPROC_SMB_DBG ++ printk(KERN_DEBUG "\n ==== Got block_base_addr=0x%08X\n", (unsigned int)dev->block_base_addr); ++ /* iproc_dump_smb_regs(dev); */ ++#endif /* IPROC_SMB_DBG */ ++ ++ dev->enable_evts = ENABLE_INTR; /* Default value, can be changed after ++ initial testing */ ++ ++ platform_set_drvdata(pdev, dev); ++ ++ /* Init internal regs, disable intrs (and then clear intrs), set fifo ++ * thresholds, etc. ++ */ ++ iproc_smbus_block_init(dev); ++ ++ /* Register ISR handler */ ++ rc = request_irq(dev->irq, iproc_smb_isr, IRQF_SHARED, pdev->name, dev); ++ ++ if (rc) { ++ printk(KERN_ERR "%s: failed to request irq %d, rc=%d\n", __func__, dev->irq, rc); ++ goto err_smb_deinit; ++ } ++ ++#ifdef IPROC_SMB_DBG ++ printk(KERN_DEBUG "\nrequest_irq succeeded\n"); ++#endif /* IPROC_SMB_DBG */ ++ ++ adap = &dev->adapter; ++ i2c_set_adapdata(adap, dev); /* Verify if this place is OK */ ++ adap->owner = THIS_MODULE; ++ adap->class = UINT_MAX; /* Can be used by any I2C device */ ++ adap->algo = &iproc_smb_algorithm; ++ adap->dev.parent = &pdev->dev; /* */ ++#ifndef CONFIG_OF ++ adap->nr = pdev->id; ++#else ++ if (of_property_read_u32(dn, "#bus-id", &smb_bus_id)) { ++ dev_warn(&pdev->dev, "missing #bus-id property (default to 0)\n"); ++ smb_bus_id = 0; ++ } ++ adap->nr = smb_bus_id; ++ pdev->id = smb_bus_id; ++ adap->dev.of_node = pdev->dev.of_node; /* needed for adding I2C child devices */ ++#endif /* CONFIG_OF */ ++ snprintf(adap->name, sizeof(adap->name), "iproc-smb%d", pdev->id); ++ ++ /* ++ * I2C device drivers may be active on return from ++ * i2c_add_numbered_adapter() ++ */ ++ rc = i2c_add_numbered_adapter(adap); ++ ++ if (rc) { ++ printk(KERN_ERR "%s: Failed to add I2C adapter, rc=%d\n", __func__, rc); ++ goto err_free_irq; ++ } ++ ++#ifdef IPROC_SMB_DBG ++ printk(KERN_DEBUG "\ni2c_add_numbered_adapter succeeded\n"); ++#endif /* IPROC_SMB_DBG */ ++ ++ /* Turn on default set of interrupts */ ++ /* For Rx, enable RX fifo full, threshold hit interrupts. Other rx ++ * interrupts will be set in the read/recv transactions, as required ++ * For Tx, enable fifo under run intr. Other intrs will be set in send ++ * write access functions ++ */ ++ iproc_intr_enable(dev, CCB_SMB_MSTRRXFIFOFULLEN_MASK); ++ ++#ifdef IPROC_SMB_DBG ++ printk(KERN_DEBUG "\niproc_intr_enable complete, intrs enabled\n"); ++#endif /* IPROC_SMB_DBG */ ++ ++ rc = proc_init(pdev); ++ ++ if (rc) { ++ printk(KERN_ERR "%s: Failed to install procfs entry, rc=%d\n", __func__, rc); ++ goto err_proc_term; ++ } ++ ++ dev->next = iproc_smbus_list; ++ iproc_smbus_list = dev; ++ ++#ifdef IPROC_SMB_DBG ++ iproc_dump_smb_regs(dev); ++ printk(KERN_DEBUG "%s: probe successful", __func__); ++#endif /* IPROC_SMB_DBG */ ++ ++ return 0; ++ ++err_proc_term: ++ proc_term(pdev); ++ ++err_free_irq: ++ free_irq(dev->irq, dev); ++ ++err_smb_deinit: ++ iproc_smbus_block_deinit(dev); ++ ++ iounmap(dev->block_base_addr); ++ ++ platform_set_drvdata(pdev, NULL); ++ ++err_free_dev_mem: ++ kfree(dev); ++ ++err_release_mem_region: ++ release_mem_region(iomem->start, resource_size(iomem)); ++ ++ printk(KERN_ERR "%s: probe failed, error=%d", __func__, rc); ++ ++ return (rc); ++} ++ ++static int iproc_smb_remove(struct platform_device *pdev) ++{ ++ struct iproc_smb_drv_int_data *dev = platform_get_drvdata(pdev); ++ struct resource *iomem; ++ unsigned int regval; ++ ++ /* Disable interrupts. */ ++ /* Verify: Should we wait for any in-progress xact to complete? */ ++ iproc_intr_disable(dev, ~0); ++ ++ /* Disable SMbus block */ ++ regval = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_CFG_REG); ++ ++ regval &= ~CCB_SMB_CFG_SMBEN_MASK; ++ ++ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_CFG_REG, regval); ++ ++ i2c_del_adapter(&dev->adapter); ++ ++ platform_set_drvdata(pdev, NULL); ++ ++ free_irq(dev->irq, dev); ++ ++ iproc_smbus_block_deinit(dev); ++ ++ iounmap(dev->block_base_addr); ++ ++ kfree(dev); ++ ++ iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ ++ release_mem_region(iomem->start, resource_size(iomem)); ++ ++ return 0; ++} ++ ++#ifndef CONFIG_OF ++static int iproc_smb_suspend(struct platform_device *pdev, pm_message_t state) ++{ ++/* struct iproc_smb_drv_int_data *dev = platform_get_drvdata(pdev); */ ++ ++ /* Add additional processing, if required */ ++ ++ return (0); ++} ++ ++static int iproc_smb_resume(struct platform_device *pdev) ++{ ++/* struct iproc_smb_drv_int_data *dev = platform_get_drvdata(pdev); */ ++ ++ /* Add additional processing, if required */ ++ ++ return (0); ++} ++ ++static struct platform_driver iproc_smb_driver = { ++ .driver = { ++ .name = "iproc-smb", ++ .owner = THIS_MODULE, ++ }, ++ .probe = iproc_smb_probe, ++ .remove = iproc_smb_remove, ++ .suspend = iproc_smb_suspend, ++ .resume = iproc_smb_resume, ++}; ++ ++static int __init iproc_smb_init(void) ++{ ++ int rc; ++ ++#ifdef IPROC_SMB_DBG ++ printk(KERN_DEBUG "%s: Entering init", __func__); ++#endif /* IPROC_SMB_DBG */ ++ ++ gProcParent = proc_mkdir(PROC_GLOBAL_PARENT_DIR, NULL); ++ ++ if (gProcParent == NULL) { ++ ++ printk(KERN_ERR "%s: SMBus driver procfs failed\n", __func__); ++ ++ return -ENOMEM; ++ ++ } ++ ++#ifdef IPROC_SMB_DBG ++ printk(KERN_DEBUG "\nproc_mkdir succeeded, gProcParent=0x%08X\n", (unsigned int)gProcParent); ++#endif /* IPROC_SMB_DBG */ ++ ++ rc = platform_driver_register(&iproc_smb_driver); ++ ++ if (rc < 0) { ++ ++ printk(KERN_ERR "%s: SMBus driver init failed, error %d\n", __func__, rc); ++ ++ } ++ ++#ifdef IPROC_SMB_DBG ++ printk(KERN_DEBUG "\n%s: Called platform_driver_register, rc=%d\n", __func__, rc); ++#endif /* IPROC_SMB_DBG */ ++ ++ ++ iproc_smbus_list = NULL; ++ ++ /* Should we set RESET bit (reg 0x0) here?: Not necessary as per hw engg */ ++ ++ return rc; ++} ++ ++static void __exit iproc_smb_exit(void) ++{ ++ platform_driver_unregister(&iproc_smb_driver); ++ ++ remove_proc_entry(PROC_GLOBAL_PARENT_DIR, NULL); ++} ++ ++module_init(iproc_smb_init); ++module_exit(iproc_smb_exit); ++ ++#else /* CONFIG_OF */ ++ ++static const struct of_device_id bcm_iproc_i2c_of_match[] = { ++ { .compatible = "brcm,iproc-i2c" }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, bcm_iproc_i2c_of_match); ++ ++static struct platform_driver bcm_iproc_i2c_driver = { ++ .driver = { ++ .name = "bcm-iproc-i2c", ++ .of_match_table = bcm_iproc_i2c_of_match, ++ }, ++ .probe = iproc_smb_probe, ++ .remove = iproc_smb_remove, ++}; ++module_platform_driver(bcm_iproc_i2c_driver); ++#endif /* !CONFIG_OF */ ++ ++MODULE_AUTHOR("Broadcom Corporation"); ++MODULE_DESCRIPTION("IPROC I2C (SMBus) Bus Driver"); ++MODULE_LICENSE("GPL"); +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig +--- a/drivers/mmc/host/Kconfig 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/mmc/host/Kconfig 2017-11-09 17:53:42.449278000 +0800 +@@ -786,3 +786,12 @@ config MMC_MTK + If you have a machine with a integrated SD/MMC card reader, say Y or M here. + This is needed if support for any SD/SDIO/MMC devices is required. + If unsure, say N. ++ ++config MMC_SDHCI_XGS_IPROC ++ tristate "Broadcom XGS iProc SD/MMC Card Interface support" ++ select MMC_SDHCI_IO_ACCESSORS ++ default n ++ help ++ This selects the platform Secure Digital Host Controller Interface. ++ If unsure, say N. ++ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile +--- a/drivers/mmc/host/Makefile 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/mmc/host/Makefile 2017-11-09 17:53:42.457283000 +0800 +@@ -75,6 +75,7 @@ obj-$(CONFIG_MMC_SDHCI_BCM2835) += sdhc + obj-$(CONFIG_MMC_SDHCI_IPROC) += sdhci-iproc.o + obj-$(CONFIG_MMC_SDHCI_MSM) += sdhci-msm.o + obj-$(CONFIG_MMC_SDHCI_ST) += sdhci-st.o ++obj-$(CONFIG_MMC_SDHCI_XGS_IPROC) += sdhci-bcm-hr3.o sdhci-xgs-iproc.o + + ifeq ($(CONFIG_CB710_DEBUG),y) + CFLAGS-cb710-mmc += -DDEBUG +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/mmc/host/sdhci-bcm-hr3.c b/drivers/mmc/host/sdhci-bcm-hr3.c +--- a/drivers/mmc/host/sdhci-bcm-hr3.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/mmc/host/sdhci-bcm-hr3.c 2017-11-09 17:53:42.528279000 +0800 +@@ -0,0 +1,611 @@ ++/* ++ * drivers/mmc/host/sdhci-bcm-hr3 - Broadcom HR3 SDHCI Platform driver ++ * ++ * Copyright (C) 2014-2016, Broadcom Corporation. All Rights Reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 and ++ * only 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 ++#include ++#include ++#include ++#include ++#include ++#include "sdhci.h" ++ ++struct sdhci_xgs_iproc_data { ++ struct sdhci_host *host; ++ struct clk *clk; ++ unsigned host_num; ++}; ++ ++struct xgs_iproc_sdhci_host { ++ struct sdhci_host host; ++ void __iomem *wrap_base; ++ void __iomem *idm_base; ++ void __iomem *cmicd_base; ++ u32 shadow_cmd; ++ u32 shadow_blk; ++}; ++ ++extern void __iomem *get_iproc_wrap_ctrl_base(void); ++static int iproc_top_sdio_config(void __iomem *cmicd_base); ++ ++static inline void ++iproc_sdhci_writel(struct sdhci_host *host, u32 val, int reg) ++{ ++ /* WAR for SDIO/GPIO setting might be reset by SDK for HR3. */ ++ if (reg == SDHCI_INT_STATUS) { ++ struct xgs_iproc_sdhci_host *iproc_host = (struct xgs_iproc_sdhci_host *)host; ++ iproc_top_sdio_config(iproc_host->cmicd_base); ++ } ++ ++ writel(val, host->ioaddr + reg); ++} ++ ++static inline u32 ++iproc_sdhci_readl(struct sdhci_host *host, int reg) ++{ ++ return readl(host->ioaddr + reg); ++} ++ ++static void ++iproc_sdhci_writew(struct sdhci_host *host, u16 val, int reg) ++{ ++ struct xgs_iproc_sdhci_host *iproc_host = (struct xgs_iproc_sdhci_host *)host; ++ u32 oldval, newval; ++ u32 word_num = (reg >> 1) & 1; ++ u32 word_shift = word_num * 16; ++ u32 mask = 0xffff << word_shift; ++ ++ if (reg == SDHCI_COMMAND) { ++ if (iproc_host->shadow_blk != 0) { ++ iproc_sdhci_writel(host, iproc_host->shadow_blk, SDHCI_BLOCK_SIZE); ++ iproc_host->shadow_blk = 0; ++ } ++ oldval = iproc_host->shadow_cmd; ++ } else if (reg == SDHCI_BLOCK_SIZE || reg == SDHCI_BLOCK_COUNT) { ++ oldval = iproc_host->shadow_blk; ++ } else { ++ oldval = iproc_sdhci_readl(host, reg & ~3); ++ } ++ newval = (oldval & ~mask) | (val << word_shift); ++ ++ if (reg == SDHCI_TRANSFER_MODE) { ++ iproc_host->shadow_cmd = newval; ++ } else if (reg == SDHCI_BLOCK_SIZE || reg == SDHCI_BLOCK_COUNT) { ++ iproc_host->shadow_blk = newval; ++ } else { ++ iproc_sdhci_writel(host, newval, reg & ~3); ++ } ++} ++ ++static u16 ++iproc_sdhci_readw(struct sdhci_host *host, int reg) ++{ ++ u32 val, word; ++ u32 word_num = (reg >> 1) & 1; ++ u32 word_shift = word_num * 16; ++ ++ val = iproc_sdhci_readl(host, (reg & ~3)); ++ word = (val >> word_shift) & 0xffff; ++ return word; ++} ++ ++static void ++iproc_sdhci_writeb(struct sdhci_host *host, u8 val, int reg) ++{ ++ u32 oldval, newval; ++ u32 byte_num = reg & 3; ++ u32 byte_shift = byte_num * 8; ++ u32 mask = 0xff << byte_shift; ++ ++ oldval = iproc_sdhci_readl(host, reg & ~3); ++ newval = (oldval & ~mask) | (val << byte_shift); ++ ++ iproc_sdhci_writel(host, newval, reg & ~3); ++} ++ ++static u8 ++iproc_sdhci_readb(struct sdhci_host *host, int reg) ++{ ++ u32 val, byte; ++ u32 byte_num = reg & 3; ++ u32 byte_shift = byte_num * 8; ++ ++ val = iproc_sdhci_readl(host, (reg & ~3)); ++ byte = (val >> byte_shift) & 0xff; ++ return byte; ++} ++ ++static u32 ++iproc_sdhci_get_max_clock(struct sdhci_host *host) ++{ ++ unsigned long max_clock; ++ ++ max_clock = (host->caps & SDHCI_CLOCK_V3_BASE_MASK) ++ >> SDHCI_CLOCK_BASE_SHIFT; ++ max_clock *= 1000000; ++ ++ return max_clock; ++} ++ ++static u32 ++iproc_sdhci_get_min_clock(struct sdhci_host *host) ++{ ++ return (host->max_clk / SDHCI_MAX_DIV_SPEC_300); ++} ++ ++static int ++iproc_sdhci_execute_tuning(struct sdhci_host *host, u32 opcode) ++{ ++ /* ++ * Tuning is unnecessary for SDR50 and DDR50; moreover, the IPROC platform ++ * doesn't support SDR104, HS200 and Hs400 cards. So, we needn't do anything ++ * for tuning. ++ */ ++ return 0; ++} ++ ++static void ++iproc_sdhci_set_clock(struct sdhci_host *host, unsigned int clock) ++{ ++ /* ++ * WAR that IPROC SD/MMC host need to set the driver strength ++ * to TYPE_A in 3.3v DS/HS mode even if the driver strength is ++ * meaningless for 3.3V signaling. ++ */ ++ if ((host->timing == MMC_TIMING_LEGACY) || ++ (host->timing == MMC_TIMING_MMC_HS) || ++ (host->timing == MMC_TIMING_SD_HS)) { ++ host->mmc->ios.drv_type = MMC_SET_DRIVER_TYPE_A; ++ } ++ ++ sdhci_set_clock(host, clock); ++} ++ ++static struct sdhci_ops sdhci_xgs_iproc_ops = { ++#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS ++ .write_l = iproc_sdhci_writel, ++ .write_w = iproc_sdhci_writew, ++ .write_b = iproc_sdhci_writeb, ++ .read_l = iproc_sdhci_readl, ++ .read_w = iproc_sdhci_readw, ++ .read_b = iproc_sdhci_readb, ++#else ++#error The iproc SDHCI driver needs CONFIG_MMC_SDHCI_IO_ACCESSORS to be set ++#endif ++ .reset = sdhci_reset, ++ .set_bus_width = sdhci_set_bus_width, ++ .set_uhs_signaling = sdhci_set_uhs_signaling, ++ .set_clock = iproc_sdhci_set_clock, ++ .get_max_clock = iproc_sdhci_get_max_clock, ++ .get_min_clock = iproc_sdhci_get_min_clock, ++ .platform_execute_tuning = iproc_sdhci_execute_tuning, ++}; ++ ++#define IPROC_CMICD_COMPATIBLE "brcm,iproc-cmicd" ++ ++#define CMIC_SBUS_RING_MAP_0_7(base) (base + 0x10098) ++#define CMIC_SBUS_RING_MAP_8_15(base) (base + 0x1009C) ++#define CMIC_SBUS_RING_MAP_16_23(base) (base + 0x100A0) ++#define CMIC_SBUS_RING_MAP_24_31(base) (base + 0x100A4) ++#define CMIC_COMMON_SCHAN_CTRL(base) (base + 0x10000) ++#define CMIC_COMMON_SCHAN_MESSAGE0(base) (base + 0x1000C) ++#define CMIC_COMMON_SCHAN_MESSAGE1(base) (base + 0x10010) ++#define CMIC_COMMON_SCHAN_MESSAGE2(base) (base + 0x10014) ++ ++/* TOP registers */ ++#define TOP_SDIO_MISC_CONTROL 0x0207e500 ++#define TOP_SDIO_MISC_CONTROL__TOP_SDIO_8B_INF 4 ++#define TOP_SDIO_MISC_CONTROL__TOP_SDIO_GPIO_INF_SEL_R 0 ++ ++/* SDIO IDM registers */ ++#define SDIO_IDM0_IO_CONTROL_DIRECT(base) (base + 0x0) ++#define SDIO_IDM0_IO_CONTROL_DIRECT__CMD_COMFLICT_DISABLE 22 ++#define SDIO_IDM0_IO_CONTROL_DIRECT__FEEDBACK_CLK_EN 21 ++#define SDIO_IDM0_IO_CONTROL_DIRECT__clk_enable 0 ++#define SDIO_IDM0_IDM_RESET_CONTROL(base) (base + 0x3F8) ++ ++/* IPROC WRAP registers */ ++#define IPROC_WRAP_SDIO_CONTROL(base) (base + 0xb0) ++#define IPROC_WRAP_SDIO_CONTROL1(base) (base + 0xb4) ++#define IPROC_WRAP_SDIO_CONTROL2(base) (base + 0xb8) ++#define IPROC_WRAP_SDIO_CONTROL3(base) (base + 0xbc) ++#define IPROC_WRAP_SDIO_CONTROL4(base) (base + 0xc0) ++#define IPROC_WRAP_SDIO_CONTROL5(base) (base + 0xc4) ++#define IPROC_WRAP_SDIO_1P8_FAIL_CONTROL(base) (base + 0xc8) ++#define IPROC_WRAP_SDIO_1P8_FAIL_CONTROL__SDIO_VDDO_18V_FAIL_SOVW 1 ++#define IPROC_WRAP_SDIO_1P8_FAIL_CONTROL__SDIO_UHS1_18V_VREG_FAIL 0 ++ ++/* ++ * SDIO_CAPS_L ++ * ++ * Field Bit(s) ++ * =========================== ++ * DDR50 31 ++ * SDR104 30 ++ * SDR50 29 ++ * SLOTTYPE 28:27 ++ * ASYNCHIRQ 26 ++ * SYSBUS64 25 ++ * V18 24 ++ * V3 23 ++ * V33 22 ++ * SUPRSM 21 ++ * SDMA 20 ++ * HSPEED 19 ++ * ADMA2 18 ++ * EXTBUSMED 17 ++ * MAXBLK 16:15 ++ * BCLK 14:7 ++ * TOUT 6 ++ * TOUTFREQ 5:0 ++ */ ++#define SDIO_CAPS_L 0xA17f6470 ++ ++/* ++ * SDIO_CAPS_H ++ * ++ * Field Bit(s) ++ * =========================== ++ * reserved 31:20 ++ * SPIBLOCKMODE 19 ++ * SPIMODE_CAP 18 ++ * CLOCKMULT 17:10 ++ * RETUNE_MODE 9:8 ++ * USETUNE_SDR50 7 ++ * TMRCNT_RETUNE 6:3 ++ * DRVR_TYPED 2 ++ * DRVR_TYPEC 1 ++ * DRVR_TYPEA 0 ++ */ ++#define SDIO_CAPS_H 0x000C000f ++ ++/* ++ * Preset value ++ * ++ * Field Bit(s) ++ * =========================== ++ * Driver Strength 12:11 ++ * Clock Generator 10 ++ * SDCLK Frequeency 9:0 ++ */ ++ ++/* ++ * SDIO_PRESETVAL1 ++ * ++ * Field Bit(s) Description ++ * ============================================================ ++ * DDR50_PRESET 25:13 Preset Value for DDR50 ++ * DEFAULT_PRESET 12:0 Preset Value for Default Speed ++ */ ++#define SDIO_PRESETVAL1 0x01004004 ++ ++/* ++ * SDIO_PRESETVAL2 ++ * ++ * Field Bit(s) Description ++ * ============================================================ ++ * HIGH_SPEED_PRESET 25:13 Preset Value for High Speed ++ * INIT_PRESET 12:0 Preset Value for Initialization ++ */ ++#define SDIO_PRESETVAL2 0x01004100 ++ ++/* ++ * SDIO_PRESETVAL3 ++ * ++ * Field Bit(s) Description ++ * ============================================================ ++ * SDR104_PRESET 25:13 Preset Value for SDR104 ++ * SDR12_PRESET 12:0 Preset Value for SDR12 ++ */ ++#define SDIO_PRESETVAL3 0x00000004 ++ ++/* ++ * SDIO_PRESETVAL4 ++ * ++ * Field Bit(s) Description ++ * ============================================================ ++ * SDR25_PRESET 25:13 Preset Value for SDR25 ++ * SDR50_PRESET 12:0 Preset Value for SDR50 ++ */ ++#define SDIO_PRESETVAL4 0x01005001 ++ ++u32 ++cmicd_schan_read(void __iomem *base, u32 ctrl, u32 addr) { ++ u32 read = 0x0; ++ ++ writel(ctrl, CMIC_COMMON_SCHAN_MESSAGE0(base)); ++ writel(addr, CMIC_COMMON_SCHAN_MESSAGE1(base)); ++ ++ writel(0x1, CMIC_COMMON_SCHAN_CTRL(base)); ++ ++ while (read != 0x2) { ++ read = readl(CMIC_COMMON_SCHAN_CTRL(base)); ++ } ++ read = readl(CMIC_COMMON_SCHAN_MESSAGE1(base)); ++ return read; ++} ++ ++u32 ++cmicd_schan_write(void __iomem *base, u32 ctrl, u32 addr, u32 val) { ++ u32 read = 0x0; ++ ++ writel(ctrl, CMIC_COMMON_SCHAN_MESSAGE0(base)); ++ writel(addr, CMIC_COMMON_SCHAN_MESSAGE1(base)); ++ writel(val, CMIC_COMMON_SCHAN_MESSAGE2(base)); ++ ++ writel(0x1, CMIC_COMMON_SCHAN_CTRL(base)); ++ ++ while (read != 0x2) { ++ read = readl(CMIC_COMMON_SCHAN_CTRL(base)); ++ } ++ return read; ++} ++ ++static void ++cmicd_init_soc(void __iomem *base) { ++ /* Configure SBUS Ring Map for TOP, block id = 16, ring number = 4 */ ++ writel(0x11112200, CMIC_SBUS_RING_MAP_0_7(base)); ++ writel(0x00430001, CMIC_SBUS_RING_MAP_8_15(base)); ++ writel(0x00005064, CMIC_SBUS_RING_MAP_16_23(base)); ++ writel(0x00000000, CMIC_SBUS_RING_MAP_24_31(base)); ++} ++ ++static int ++iproc_top_sdio_config(void __iomem *cmicd_base) ++{ ++ u32 val; ++ ++ cmicd_init_soc(cmicd_base); ++ ++ /* Enable SDIO 8 bit mode */ ++ val = cmicd_schan_read(cmicd_base, 0x2c800200, TOP_SDIO_MISC_CONTROL); ++ if ((val & 0x1f) != 0x1f) { ++ val |= (0x1 << TOP_SDIO_MISC_CONTROL__TOP_SDIO_8B_INF); ++ val |= (0xf << TOP_SDIO_MISC_CONTROL__TOP_SDIO_GPIO_INF_SEL_R); ++ cmicd_schan_write(cmicd_base, 0x34800200, TOP_SDIO_MISC_CONTROL, val); ++ } ++ ++ return 0; ++} ++ ++static int ++iproc_sdio_init(struct xgs_iproc_sdhci_host *iproc_host) ++{ ++ int ret = 0; ++ u32 val; ++ ++ /* Enable SDIO for SDIO/GPIO selection */ ++ ret = iproc_top_sdio_config(iproc_host->cmicd_base); ++ if (ret < 0) { ++ return ret; ++ } ++ ++ /* Release reset */ ++ writel(0x1, SDIO_IDM0_IDM_RESET_CONTROL(iproc_host->idm_base)); ++ udelay(1000); ++ writel(0x0, SDIO_IDM0_IDM_RESET_CONTROL(iproc_host->idm_base)); ++ ++ /* Enable the SDIO clock */ ++ val = readl(SDIO_IDM0_IO_CONTROL_DIRECT(iproc_host->idm_base)); ++ val |= (1 << SDIO_IDM0_IO_CONTROL_DIRECT__CMD_COMFLICT_DISABLE); ++ val |= (1 << SDIO_IDM0_IO_CONTROL_DIRECT__FEEDBACK_CLK_EN); ++ val |= (1 << SDIO_IDM0_IO_CONTROL_DIRECT__clk_enable); ++ writel(val, SDIO_IDM0_IO_CONTROL_DIRECT(iproc_host->idm_base)); ++ ++ /* Set the 1.8v fail control for HR3. ++ * This setting will not impact the uboot SD/MMC driver, since uboot doesn't ++ * support 1.8v. The 1.8v SDIO will be supportted in Kernel. ++ */ ++ val = readl(IPROC_WRAP_SDIO_1P8_FAIL_CONTROL(iproc_host->wrap_base)); ++ val |= (1 << IPROC_WRAP_SDIO_1P8_FAIL_CONTROL__SDIO_VDDO_18V_FAIL_SOVW); ++ val &= ~(1 << IPROC_WRAP_SDIO_1P8_FAIL_CONTROL__SDIO_UHS1_18V_VREG_FAIL); ++ writel(val, IPROC_WRAP_SDIO_1P8_FAIL_CONTROL(iproc_host->wrap_base)); ++ ++ /* ++ * Configure SDIO host controller capabilities ++ * (common setting for all SDIO controllers) ++ */ ++ writel(SDIO_CAPS_H, IPROC_WRAP_SDIO_CONTROL(iproc_host->wrap_base)); ++ writel(SDIO_CAPS_L, IPROC_WRAP_SDIO_CONTROL1(iproc_host->wrap_base)); ++ ++ /* ++ * Configure SDIO host controller preset values ++ * (common setting for all SDIO controllers) ++ */ ++ writel(SDIO_PRESETVAL1, IPROC_WRAP_SDIO_CONTROL2(iproc_host->wrap_base)); ++ writel(SDIO_PRESETVAL2, IPROC_WRAP_SDIO_CONTROL3(iproc_host->wrap_base)); ++ writel(SDIO_PRESETVAL3, IPROC_WRAP_SDIO_CONTROL4(iproc_host->wrap_base)); ++ writel(SDIO_PRESETVAL4, IPROC_WRAP_SDIO_CONTROL5(iproc_host->wrap_base)); ++ ++ return 0; ++} ++ ++static int ++sdhci_xgs_iproc_probe(struct platform_device *pdev) ++{ ++ struct xgs_iproc_sdhci_host *iproc_host; ++ struct sdhci_host *host; ++ struct sdhci_xgs_iproc_data *data; ++ struct device_node *np = pdev->dev.of_node; ++ int ret = 0; ++ ++ /* allocate SDHCI host + platform data memory */ ++ host = sdhci_alloc_host(&pdev->dev, sizeof(struct sdhci_xgs_iproc_data)); ++ if (IS_ERR(host)) { ++ printk(KERN_ERR "SDIO%d: Unable to allocate SDHCI host\n", pdev->id); ++ return PTR_ERR(host); ++ } ++ ++ iproc_host = (struct xgs_iproc_sdhci_host *)host; ++ ++ /* set up data structure */ ++ data = sdhci_priv(host); ++ data->host = host; ++ data->host_num = pdev->id; ++ host->hw_name = "IPROC-SDIO"; ++ host->ops = &sdhci_xgs_iproc_ops; ++ host->mmc->caps = MMC_CAP_8_BIT_DATA; ++ host->quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | ++ SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12; ++ host->irq = (unsigned int)irq_of_parse_and_map(np, 0); ++ host->ioaddr = (void *)of_iomap(np, 0); ++ if (!host->ioaddr) { ++ printk(KERN_ERR "SDIO%d: Unable to iomap SDIO registers\n", pdev->id); ++ ret = -ENXIO; ++ goto err_free_host; ++ } ++ ++ iproc_host->idm_base = of_iomap(np, 1); ++ if (!iproc_host->idm_base) { ++ printk(KERN_ERR "Unable to iomap SDIO IDM base address\n"); ++ ret = -ENXIO; ++ goto err_iounmap; ++ } ++ ++ np = of_find_compatible_node(NULL, NULL, IPROC_CMICD_COMPATIBLE); ++ if (!np) { ++ printk(KERN_ERR "Failed to find IPROC_CMICD defined in DT\n"); ++ ret = -ENODEV; ++ goto err_iounmap; ++ } ++ ++ iproc_host->cmicd_base = of_iomap(np, 0); ++ if (!iproc_host->cmicd_base) { ++ printk(KERN_ERR "Unable to iomap IPROC CMICD base address\n"); ++ ret = -ENXIO; ++ goto err_iounmap; ++ } ++ ++ iproc_host->wrap_base = get_iproc_wrap_ctrl_base(); ++ if (!iproc_host->wrap_base) { ++ printk(KERN_ERR "Unable to get IPROC WRAP base address\n"); ++ ret = -ENXIO; ++ goto err_iounmap; ++ } ++ ++ ret = iproc_sdio_init(iproc_host); ++ if (ret < 0) { ++ printk(KERN_ERR "SDIO%d: SDIO initial failed\n", pdev->id); ++ ret = -ENXIO; ++ goto err_iounmap; ++ } ++ ++ platform_set_drvdata(pdev, data); ++ ++ ret = sdhci_add_host(host); ++ if (ret) { ++ printk(KERN_ERR "SDIO%d: Failed to add SDHCI host\n", pdev->id); ++ goto err_iounmap; ++ } ++ ++ return ret; ++ ++err_iounmap: ++ if (iproc_host->idm_base) ++ iounmap(iproc_host->idm_base); ++ if (iproc_host->cmicd_base) ++ iounmap(iproc_host->cmicd_base); ++ if (host->ioaddr) ++ iounmap(host->ioaddr); ++ ++err_free_host: ++ sdhci_free_host(host); ++ ++ return ret; ++} ++ ++static int __exit ++sdhci_xgs_iproc_remove(struct platform_device *pdev) ++{ ++ struct sdhci_xgs_iproc_data *data = platform_get_drvdata(pdev); ++ struct sdhci_host *host = data->host; ++ struct xgs_iproc_sdhci_host *iproc_host = (struct xgs_iproc_sdhci_host *)host; ++ ++ sdhci_remove_host(host, 0); ++ platform_set_drvdata(pdev, NULL); ++ ++ if (iproc_host->idm_base) ++ iounmap(iproc_host->idm_base); ++ if (iproc_host->cmicd_base) ++ iounmap(iproc_host->cmicd_base); ++ if (host->ioaddr) ++ iounmap(host->ioaddr); ++ ++ sdhci_free_host(host); ++ release_mem_region(pdev->resource[0].start, ++ pdev->resource[0].end - pdev->resource[0].start + 1); ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++static int ++sdhci_xgs_iproc_suspend(struct platform_device *pdev, pm_message_t state) ++{ ++ int ret = 0; ++ struct sdhci_xgs_iproc_data *data = platform_get_drvdata(pdev); ++ ++ ret = sdhci_suspend_host(data->host); ++ if (ret < 0) { ++ printk("%s: %d\n", __FILE__, __LINE__); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int ++sdhci_xgs_iproc_resume(struct platform_device *pdev) ++{ ++ int ret = 0; ++ struct sdhci_xgs_iproc_data *data = platform_get_drvdata(pdev); ++ ++ ret = sdhci_resume_host(data->host); ++ if (ret < 0) { ++ printk("%s: %d\n", __FILE__, __LINE__); ++ return ret; ++ } ++ return 0; ++} ++#else /* CONFIG_PM */ ++ ++#define sdhci_xgs_iproc_suspend NULL ++#define sdhci_xgs_iproc_resume NULL ++ ++#endif /* CONFIG_PM */ ++ ++ ++static const struct of_device_id brcm_iproc_hr3_dt_ids[] = { ++ { .compatible = "brcm,iproc-hr3-sdio"}, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, brcm_iproc_dt_ids); ++ ++static struct platform_driver sdhci_xgs_iproc_driver = { ++ .probe = sdhci_xgs_iproc_probe, ++ .remove = __exit_p(sdhci_xgs_iproc_remove), ++ .suspend = sdhci_xgs_iproc_suspend, ++ .resume = sdhci_xgs_iproc_resume, ++ .driver = { ++ .name = "iproc-hr3-sdio", ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(brcm_iproc_hr3_dt_ids), ++ }, ++}; ++ ++module_platform_driver(sdhci_xgs_iproc_driver); ++ ++MODULE_AUTHOR("Broadcom"); ++MODULE_DESCRIPTION("SDHCI XGS HR3 driver"); ++MODULE_LICENSE("GPL"); +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/mmc/host/sdhci-xgs-iproc.c b/drivers/mmc/host/sdhci-xgs-iproc.c +--- a/drivers/mmc/host/sdhci-xgs-iproc.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/mmc/host/sdhci-xgs-iproc.c 2017-11-09 17:53:42.564288000 +0800 +@@ -0,0 +1,311 @@ ++/* ++ * drivers/mmc/host/sdhci-iproc.c - Broadcom IPROC SDHCI Platform driver ++ * ++ * Copyright (C) 2014-2016, Broadcom Corporation. All Rights Reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 and ++ * only 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 ++#include ++#include ++#include ++#include ++#include ++#include "sdhci.h" ++ ++struct sdhci_xgs_iproc_data { ++ struct sdhci_host *host; ++ struct clk *clk; ++ unsigned host_num; ++}; ++ ++struct xgs_iproc_sdhci_host { ++ struct sdhci_host host; ++ u32 shadow_cmd; ++ u32 shadow_blk; ++}; ++ ++static inline void ++iproc_sdhci_writel(struct sdhci_host *host, u32 val, int reg) ++{ ++ writel(val, host->ioaddr + reg); ++} ++ ++static inline u32 ++iproc_sdhci_readl(struct sdhci_host *host, int reg) ++{ ++ return readl(host->ioaddr + reg); ++} ++ ++static void ++iproc_sdhci_writew(struct sdhci_host *host, u16 val, int reg) ++{ ++ struct xgs_iproc_sdhci_host *iproc_host = (struct xgs_iproc_sdhci_host *)host; ++ u32 oldval, newval; ++ u32 word_num = (reg >> 1) & 1; ++ u32 word_shift = word_num * 16; ++ u32 mask = 0xffff << word_shift; ++ ++ if (reg == SDHCI_COMMAND) { ++ if (iproc_host->shadow_blk != 0) { ++ iproc_sdhci_writel(host, iproc_host->shadow_blk, SDHCI_BLOCK_SIZE); ++ iproc_host->shadow_blk = 0; ++ } ++ oldval = iproc_host->shadow_cmd; ++ } else if (reg == SDHCI_BLOCK_SIZE || reg == SDHCI_BLOCK_COUNT) { ++ oldval = iproc_host->shadow_blk; ++ } else { ++ oldval = iproc_sdhci_readl(host, reg & ~3); ++ } ++ newval = (oldval & ~mask) | (val << word_shift); ++ ++ if (reg == SDHCI_TRANSFER_MODE) { ++ iproc_host->shadow_cmd = newval; ++ } else if (reg == SDHCI_BLOCK_SIZE || reg == SDHCI_BLOCK_COUNT) { ++ iproc_host->shadow_blk = newval; ++ } else { ++ iproc_sdhci_writel(host, newval, reg & ~3); ++ } ++} ++ ++static u16 ++iproc_sdhci_readw(struct sdhci_host *host, int reg) ++{ ++ u32 val, word; ++ u32 word_num = (reg >> 1) & 1; ++ u32 word_shift = word_num * 16; ++ ++ val = iproc_sdhci_readl(host, (reg & ~3)); ++ word = (val >> word_shift) & 0xffff; ++ return word; ++} ++ ++ ++static void ++iproc_sdhci_writeb(struct sdhci_host *host, u8 val, int reg) ++{ ++ u32 oldval, newval; ++ u32 byte_num = reg & 3; ++ u32 byte_shift = byte_num * 8; ++ u32 mask = 0xff << byte_shift; ++ ++ oldval = iproc_sdhci_readl(host, reg & ~3); ++ newval = (oldval & ~mask) | (val << byte_shift); ++ ++ iproc_sdhci_writel(host, newval, reg & ~3); ++} ++ ++static u8 ++iproc_sdhci_readb(struct sdhci_host *host, int reg) ++{ ++ u32 val, byte; ++ u32 byte_num = reg & 3; ++ u32 byte_shift = byte_num * 8; ++ ++ val = iproc_sdhci_readl(host, (reg & ~3)); ++ byte = (val >> byte_shift) & 0xff; ++ return byte; ++} ++ ++static u32 ++iproc_sdhci_get_max_clock(struct sdhci_host *host) ++{ ++ unsigned long max_clock; ++ ++ max_clock = (host->caps & SDHCI_CLOCK_V3_BASE_MASK) ++ >> SDHCI_CLOCK_BASE_SHIFT; ++ max_clock *= 1000000; ++ ++ return max_clock; ++} ++ ++static u32 ++iproc_sdhci_get_min_clock(struct sdhci_host *host) ++{ ++ return (host->max_clk / SDHCI_MAX_DIV_SPEC_300); ++} ++ ++static int ++iproc_sdhci_execute_tuning(struct sdhci_host *host, u32 opcode) ++{ ++ /* ++ * Tuning is unnecessary for SDR50 and DDR50; moreover, the IPROC platform ++ * doesn't support SDR104, HS200 and Hs400 cards. So, we needn't do anything ++ * for tuning. ++ */ ++ return 0; ++} ++ ++static void ++iproc_sdhci_set_clock(struct sdhci_host *host, unsigned int clock) ++{ ++ /* ++ * WAR that IPROC SD/MMC host need to set the driver strength ++ * to TYPE_A in 3.3v DS/HS mode even if the driver strength is ++ * meaningless for 3.3V signaling. ++ */ ++ if ((host->timing == MMC_TIMING_LEGACY) || ++ (host->timing == MMC_TIMING_MMC_HS) || ++ (host->timing == MMC_TIMING_SD_HS)) { ++ host->mmc->ios.drv_type = MMC_SET_DRIVER_TYPE_A; ++ } ++ ++ sdhci_set_clock(host, clock); ++} ++ ++static struct sdhci_ops sdhci_xgs_iproc_ops = { ++#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS ++ .write_l = iproc_sdhci_writel, ++ .write_w = iproc_sdhci_writew, ++ .write_b = iproc_sdhci_writeb, ++ .read_l = iproc_sdhci_readl, ++ .read_w = iproc_sdhci_readw, ++ .read_b = iproc_sdhci_readb, ++#else ++#error The iproc SDHCI driver needs CONFIG_MMC_SDHCI_IO_ACCESSORS to be set ++#endif ++ .reset = sdhci_reset, ++ .set_bus_width = sdhci_set_bus_width, ++ .set_uhs_signaling = sdhci_set_uhs_signaling, ++ .set_clock = iproc_sdhci_set_clock, ++ .get_max_clock = iproc_sdhci_get_max_clock, ++ .get_min_clock = iproc_sdhci_get_min_clock, ++ .platform_execute_tuning = iproc_sdhci_execute_tuning, ++}; ++ ++static int ++sdhci_xgs_iproc_probe(struct platform_device *pdev) ++{ ++ struct sdhci_host *host; ++ struct sdhci_xgs_iproc_data *data; ++ struct device_node *np = pdev->dev.of_node; ++ int ret = 0; ++ ++ /* allocate SDHCI host + platform data memory */ ++ host = sdhci_alloc_host(&pdev->dev, sizeof(struct sdhci_xgs_iproc_data)); ++ if (IS_ERR(host)) { ++ printk(KERN_ERR "SDIO%d: Unable to allocate SDHCI host\n", pdev->id); ++ return PTR_ERR(host); ++ } ++ ++ /* set up data structure */ ++ data = sdhci_priv(host); ++ data->host = host; ++ data->host_num = pdev->id; ++ host->hw_name = "IPROC-SDIO"; ++ host->ops = &sdhci_xgs_iproc_ops; ++ host->mmc->caps = MMC_CAP_8_BIT_DATA; ++ host->quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | ++ SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12; ++ ++ host->irq = (unsigned int)irq_of_parse_and_map(np, 0); ++ host->ioaddr = (void *)of_iomap(np, 0); ++ if (!host->ioaddr) { ++ printk(KERN_ERR "SDIO%d: Unable to iomap SDIO registers\n", pdev->id); ++ ret = -ENXIO; ++ goto err_free_host; ++ } ++ ++ platform_set_drvdata(pdev, data); ++ ++ ret = sdhci_add_host(host); ++ if (ret) { ++ printk(KERN_ERR "SDIO%d: Failed to add SDHCI host\n", pdev->id); ++ goto err_iounmap; ++ } ++ ++ return ret; ++ ++err_iounmap: ++ iounmap(host->ioaddr); ++ ++err_free_host: ++ sdhci_free_host(host); ++ ++ return ret; ++} ++ ++static int __exit ++sdhci_xgs_iproc_remove(struct platform_device *pdev) ++{ ++ struct sdhci_xgs_iproc_data *data = platform_get_drvdata(pdev); ++ struct sdhci_host *host = data->host; ++ ++ sdhci_remove_host(host, 0); ++ platform_set_drvdata(pdev, NULL); ++ iounmap(host->ioaddr); ++ sdhci_free_host(host); ++ release_mem_region(pdev->resource[0].start, ++ pdev->resource[0].end - pdev->resource[0].start + 1); ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++static int ++sdhci_xgs_iproc_suspend(struct platform_device *pdev, pm_message_t state) ++{ ++ int ret = 0; ++ struct sdhci_xgs_iproc_data *data = platform_get_drvdata(pdev); ++ ++ ret = sdhci_suspend_host(data->host); ++ if (ret < 0) { ++ printk("%s: %d\n", __FILE__, __LINE__); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int ++sdhci_xgs_iproc_resume(struct platform_device *pdev) ++{ ++ int ret = 0; ++ struct sdhci_xgs_iproc_data *data = platform_get_drvdata(pdev); ++ ++ ret = sdhci_resume_host(data->host); ++ if (ret < 0) { ++ printk("%s: %d\n", __FILE__, __LINE__); ++ return ret; ++ } ++ return 0; ++} ++#else /* CONFIG_PM */ ++ ++#define sdhci_xgs_iproc_suspend NULL ++#define sdhci_xgs_iproc_resume NULL ++ ++#endif /* CONFIG_PM */ ++ ++ ++static const struct of_device_id brcm_iproc_xgs_dt_ids[] = { ++ { .compatible = "brcm,iproc-xgs-sdio"}, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, brcm_iproc_dt_ids); ++ ++static struct platform_driver sdhci_xgs_iproc_driver = { ++ .probe = sdhci_xgs_iproc_probe, ++ .remove = __exit_p(sdhci_xgs_iproc_remove), ++ .suspend = sdhci_xgs_iproc_suspend, ++ .resume = sdhci_xgs_iproc_resume, ++ .driver = { ++ .name = "iproc-xgs-sdio", ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(brcm_iproc_xgs_dt_ids), ++ }, ++}; ++ ++module_platform_driver(sdhci_xgs_iproc_driver); ++ ++MODULE_AUTHOR("Broadcom"); ++MODULE_DESCRIPTION("SDHCI XGS IPROC driver"); ++MODULE_LICENSE("GPL"); +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/mtd/Makefile b/drivers/mtd/Makefile +--- a/drivers/mtd/Makefile 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/mtd/Makefile 2017-11-09 17:53:42.613320000 +0800 +@@ -33,4 +33,5 @@ inftl-objs := inftlcore.o inftlmount.o + obj-y += chips/ lpddr/ maps/ devices/ nand/ onenand/ tests/ + + obj-$(CONFIG_MTD_SPI_NOR) += spi-nor/ ++obj-$(CONFIG_MTD_SPI_NOR_IPROC) += spi-nor/ + obj-$(CONFIG_MTD_UBI) += ubi/ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig +--- a/drivers/mtd/devices/Kconfig 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/mtd/devices/Kconfig 2017-11-09 17:53:42.646279000 +0800 +@@ -95,6 +95,12 @@ config MTD_M25P80 + if you want to specify device partitioning or to use a device which + doesn't support the JEDEC ID instruction. + ++config MTD_M25P80_IPROC ++ tristate "M25P80 modified for BRCM iProc" ++ depends on SPI_MASTER && MTD_SPI_NOR_IPROC ++ help ++ This enables access to most modern SPI flash chips for BRCM iProc QSPI controller ++ + config MTD_SPEAR_SMI + tristate "SPEAR MTD NOR Support through SMI controller" + depends on PLAT_SPEAR +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile +--- a/drivers/mtd/devices/Makefile 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/mtd/devices/Makefile 2017-11-09 17:53:42.647286000 +0800 +@@ -12,6 +12,7 @@ obj-$(CONFIG_MTD_LART) += lart.o + obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o + obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o + obj-$(CONFIG_MTD_M25P80) += m25p80.o ++obj-$(CONFIG_MTD_M25P80_IPROC) += m25p80-iproc.o + obj-$(CONFIG_MTD_SPEAR_SMI) += spear_smi.o + obj-$(CONFIG_MTD_SST25L) += sst25l.o + obj-$(CONFIG_MTD_BCM47XXSFLASH) += bcm47xxsflash.o +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/mtd/devices/m25p80-iproc.c b/drivers/mtd/devices/m25p80-iproc.c +--- a/drivers/mtd/devices/m25p80-iproc.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/mtd/devices/m25p80-iproc.c 2017-11-09 17:53:42.661287000 +0800 +@@ -0,0 +1,328 @@ ++/* ++ * MTD SPI driver for ST M25Pxx (and similar) serial flash chips based ++ * on m25p80.c with BRCM iProc patch ++ * ++ * This code is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include ++#include ++#include ++ ++#define MAX_CMD_SIZE 6 ++struct m25p { ++ struct spi_device *spi; ++ struct spi_nor spi_nor; ++ u8 command[MAX_CMD_SIZE]; ++}; ++ ++static int m25p80_read_reg(struct spi_nor *nor, u8 code, u8 *val, int len) ++{ ++ struct m25p *flash = nor->priv; ++ struct spi_device *spi = flash->spi; ++ int ret; ++ ++ ret = spi_write_then_read(spi, &code, 1, val, len); ++ if (ret < 0) ++ dev_err(&spi->dev, "error %d reading %x\n", ret, code); ++ ++ return ret; ++} ++ ++static void m25p_addr2cmd(struct spi_nor *nor, unsigned int addr, unsigned int len, u8 *cmd) ++{ ++ u16 addr_width = nor->addr_width; ++ ++#ifdef CONFIG_M25PXX_STAY_IN_3BYTE_MODE ++ /* Use 4-byte mode only if (address + len) is > 16MB */ ++ if (addr + len > 0x1000000) { ++ addr_width = 4; ++ } ++#endif /* CONFIG_M25PXX_STAY_IN_3BYTE_MODE */ ++ ++ /* opcode is in cmd[0] */ ++ cmd[1] = addr >> (addr_width * 8 - 8); ++ cmd[2] = addr >> (addr_width * 8 - 16); ++ cmd[3] = addr >> (addr_width * 8 - 24); ++ cmd[4] = addr >> (addr_width * 8 - 32); ++} ++ ++static int m25p_cmdsz(struct spi_nor *nor, unsigned int addr) ++{ ++#ifdef CONFIG_M25PXX_STAY_IN_3BYTE_MODE ++ /* Use 4-byte mode only if the address is >= 16MB */ ++ if (addr >= 0x1000000) { ++ return 1 + 4; ++ } ++#endif /* CONFIG_M25PXX_STAY_IN_3BYTE_MODE */ ++ return 1 + nor->addr_width; ++} ++ ++static int m25p80_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len) ++{ ++ struct m25p *flash = nor->priv; ++ struct spi_device *spi = flash->spi; ++ ++ flash->command[0] = opcode; ++ if (buf) ++ memcpy(&flash->command[1], buf, len); ++ ++ return spi_write(spi, flash->command, len + 1); ++} ++ ++static void m25p80_write(struct spi_nor *nor, loff_t to, size_t len, ++ size_t *retlen, const u_char *buf) ++{ ++ struct m25p *flash = nor->priv; ++ struct spi_device *spi = flash->spi; ++ struct spi_transfer t[2] = {}; ++ struct spi_message m; ++ int cmd_sz = m25p_cmdsz(nor, to); ++ ++ spi_message_init(&m); ++ ++ if (nor->program_opcode == SPINOR_OP_AAI_WP && nor->sst_write_second) ++ cmd_sz = 1; ++ ++ flash->command[0] = nor->program_opcode; ++ m25p_addr2cmd(nor, to, 1, flash->command); ++ ++ t[0].tx_buf = flash->command; ++ t[0].len = cmd_sz; ++ spi_message_add_tail(&t[0], &m); ++ ++ t[1].tx_buf = buf; ++ t[1].len = len; ++ spi_message_add_tail(&t[1], &m); ++ ++ spi_sync(spi, &m); ++ ++ *retlen += m.actual_length - cmd_sz; ++} ++ ++static inline unsigned int m25p80_rx_nbits(struct spi_nor *nor) ++{ ++ switch (nor->flash_read) { ++ case SPI_NOR_DUAL: ++ return 2; ++ case SPI_NOR_QUAD: ++ return 4; ++ default: ++ return 0; ++ } ++} ++ ++/* ++ * Read an address range from the nor chip. The address range ++ * may be any size provided it is within the physical boundaries. ++ */ ++static int m25p80_read(struct spi_nor *nor, loff_t from, size_t len, ++ size_t *retlen, u_char *buf) ++{ ++ struct m25p *flash = nor->priv; ++ struct spi_device *spi = flash->spi; ++ struct spi_transfer t[2]; ++ struct spi_message m; ++ unsigned int dummy = nor->read_dummy; ++ ++ /* convert the dummy cycles to the number of bytes */ ++ dummy /= 8; ++ ++ spi_message_init(&m); ++ memset(t, 0, (sizeof t)); ++ ++ flash->command[0] = nor->read_opcode; ++ m25p_addr2cmd(nor, from, len, flash->command); ++ ++ t[0].tx_buf = flash->command; ++ t[0].len = m25p_cmdsz(nor, from + len - 1) + dummy; ++ spi_message_add_tail(&t[0], &m); ++ ++ t[1].rx_buf = buf; ++ t[1].rx_nbits = m25p80_rx_nbits(nor); ++ t[1].len = len; ++ spi_message_add_tail(&t[1], &m); ++ ++ spi_sync(spi, &m); ++ ++ *retlen = m.actual_length - m25p_cmdsz(nor, from + len - 1) - dummy; ++ return 0; ++} ++ ++static int m25p80_erase(struct spi_nor *nor, loff_t offset) ++{ ++ struct m25p *flash = nor->priv; ++ ++ dev_dbg(nor->dev, "%dKiB at 0x%08x\n", ++ flash->spi_nor.mtd.erasesize / 1024, (u32)offset); ++ ++ /* Set up command buffer. */ ++ flash->command[0] = nor->erase_opcode; ++ m25p_addr2cmd(nor, offset, 1, flash->command); ++ ++ spi_write(flash->spi, flash->command, m25p_cmdsz(nor, offset)); ++ ++ return 0; ++} ++ ++/* ++ * board specific setup should have ensured the SPI clock used here ++ * matches what the READ command supports, at least until this driver ++ * understands FAST_READ (for clocks over 25 MHz). ++ */ ++static int m25p_probe(struct spi_device *spi) ++{ ++ struct mtd_part_parser_data ppdata; ++ struct flash_platform_data *data; ++ struct m25p *flash; ++ struct spi_nor *nor; ++ enum read_mode mode = SPI_NOR_NORMAL; ++ char *flash_name = NULL; ++ int ret; ++ ++ data = dev_get_platdata(&spi->dev); ++ ++ flash = devm_kzalloc(&spi->dev, sizeof(*flash), GFP_KERNEL); ++ if (!flash) ++ return -ENOMEM; ++ ++ nor = &flash->spi_nor; ++ ++ /* install the hooks */ ++ nor->read = m25p80_read; ++ nor->write = m25p80_write; ++ nor->erase = m25p80_erase; ++ nor->write_reg = m25p80_write_reg; ++ nor->read_reg = m25p80_read_reg; ++ ++ nor->dev = &spi->dev; ++ nor->flash_node = spi->dev.of_node; ++ nor->priv = flash; ++ ++ spi_set_drvdata(spi, flash); ++ flash->spi = spi; ++ ++ if (spi->mode & SPI_RX_QUAD) ++ mode = SPI_NOR_QUAD; ++ else if (spi->mode & SPI_RX_DUAL) ++ mode = SPI_NOR_DUAL; ++ ++ if (data && data->name) ++ nor->mtd.name = data->name; ++ ++ /* For some (historical?) reason many platforms provide two different ++ * names in flash_platform_data: "name" and "type". Quite often name is ++ * set to "m25p80" and then "type" provides a real chip name. ++ * If that's the case, respect "type" and ignore a "name". ++ */ ++ if (data && data->type) ++ flash_name = data->type; ++ else ++ flash_name = spi->modalias; ++ ++ ret = spi_nor_scan(nor, flash_name, mode); ++ if (ret) ++ return ret; ++ ++ ppdata.of_node = spi->dev.of_node; ++ ++ return mtd_device_parse_register(&nor->mtd, NULL, &ppdata, ++ data ? data->parts : NULL, ++ data ? data->nr_parts : 0); ++} ++ ++ ++static int m25p_remove(struct spi_device *spi) ++{ ++ struct m25p *flash = spi_get_drvdata(spi); ++ ++ /* Clean up MTD stuff. */ ++ return mtd_device_unregister(&flash->spi_nor.mtd); ++} ++ ++/* ++ * Do NOT add to this array without reading the following: ++ * ++ * Historically, many flash devices are bound to this driver by their name. But ++ * since most of these flash are compatible to some extent, and their ++ * differences can often be differentiated by the JEDEC read-ID command, we ++ * encourage new users to add support to the spi-nor library, and simply bind ++ * against a generic string here (e.g., "jedec,spi-nor"). ++ * ++ * Many flash names are kept here in this list (as well as in spi-nor.c) to ++ * keep them available as module aliases for existing platforms. ++ */ ++static const struct spi_device_id m25p_ids[] = { ++ /* ++ * Entries not used in DTs that should be safe to drop after replacing ++ * them with "nor-jedec" in platform data. ++ */ ++ {"s25sl064a"}, {"w25x16"}, {"m25p10"}, {"m25px64"}, ++ ++ /* ++ * Entries that were used in DTs without "nor-jedec" fallback and should ++ * be kept for backward compatibility. ++ */ ++ {"at25df321a"}, {"at25df641"}, {"at26df081a"}, ++ {"mr25h256"}, ++ {"mx25l4005a"}, {"mx25l1606e"}, {"mx25l6405d"}, {"mx25l12805d"}, ++ {"mx25l25635e"},{"mx66l51235l"}, ++ {"n25q064"}, {"n25q128a11"}, {"n25q128a13"}, {"n25q512a"}, ++ {"s25fl256s1"}, {"s25fl512s"}, {"s25sl12801"}, {"s25fl008k"}, ++ {"s25fl064k"}, ++ {"sst25vf040b"},{"sst25vf016b"},{"sst25vf032b"},{"sst25wf040"}, ++ {"m25p40"}, {"m25p80"}, {"m25p16"}, {"m25p32"}, ++ {"m25p64"}, {"m25p128"}, ++ {"w25x80"}, {"w25x32"}, {"w25q32"}, {"w25q32dw"}, ++ {"w25q80bl"}, {"w25q128"}, {"w25q256"}, ++ ++ /* Flashes that can't be detected using JEDEC */ ++ {"m25p05-nonjedec"}, {"m25p10-nonjedec"}, {"m25p20-nonjedec"}, ++ {"m25p40-nonjedec"}, {"m25p80-nonjedec"}, {"m25p16-nonjedec"}, ++ {"m25p32-nonjedec"}, {"m25p64-nonjedec"}, {"m25p128-nonjedec"}, ++ ++ { }, ++}; ++MODULE_DEVICE_TABLE(spi, m25p_ids); ++ ++static const struct of_device_id m25p_of_table[] = { ++ /* ++ * Generic compatibility for SPI NOR that can be identified by the ++ * JEDEC READ ID opcode (0x9F). Use this, if possible. ++ */ ++ { .compatible = "jedec,spi-nor" }, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, m25p_of_table); ++ ++static struct spi_driver m25p80_driver = { ++ .driver = { ++ .name = "m25p80", ++ .of_match_table = m25p_of_table, ++ }, ++ .id_table = m25p_ids, ++ .probe = m25p_probe, ++ .remove = m25p_remove, ++ ++ /* REVISIT: many of these chips have deep power-down modes, which ++ * should clearly be entered on suspend() to minimize power use. ++ * And also when they're otherwise idle... ++ */ ++}; ++ ++module_spi_driver(m25p80_driver); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Mike Lavender"); ++MODULE_DESCRIPTION("MTD SPI driver for ST M25Pxx flash chips"); +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig +--- a/drivers/mtd/maps/Kconfig 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/mtd/maps/Kconfig 2017-11-09 17:53:42.700292000 +0800 +@@ -97,6 +97,15 @@ config MSP_FLASH_MAP_LIMIT + default "0x02000000" + depends on MSP_FLASH_MAP_LIMIT_32M + ++config MTD_NOR_XGS_IPROC ++ bool "Broadcom XGS iProc CFI NOR support" ++ depends on (ARCH_XGS_IPROC || COMPILE_TEST) && MTD_CFI ++ default n ++ help ++ This selects a driver for the iProc NOR support. ++ ++ If unsure, say N. ++ + config MTD_SUN_UFLASH + tristate "Sun Microsystems userflash support" + depends on SPARC && MTD_CFI && PCI +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile +--- a/drivers/mtd/maps/Makefile 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/mtd/maps/Makefile 2017-11-09 17:53:42.701291000 +0800 +@@ -43,3 +43,4 @@ obj-$(CONFIG_MTD_VMU) += vmu-flash.o + obj-$(CONFIG_MTD_GPIO_ADDR) += gpio-addr-flash.o + obj-$(CONFIG_MTD_LATCH_ADDR) += latch-addr-flash.o + obj-$(CONFIG_MTD_LANTIQ) += lantiq-flash.o ++obj-$(CONFIG_MTD_NOR_XGS_IPROC) += xgs-iproc-flash.o +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/mtd/maps/xgs-iproc-flash.c b/drivers/mtd/maps/xgs-iproc-flash.c +--- a/drivers/mtd/maps/xgs-iproc-flash.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/mtd/maps/xgs-iproc-flash.c 2017-11-09 17:53:42.757297000 +0800 +@@ -0,0 +1,229 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#define IPROC_NOR_COMPATIBLE "brcm,iproc-nor" ++extern void __iomem *get_iproc_dmu_pcu_base(void); ++ ++/* HR2 */ ++#define PNOR_NAND_SEL_REG_OVERRIDE_HR2 2 ++#define PNOR_NAND_SEL_REG_PNOR_SEL_HR2 3 ++ ++/* GH/HR3 */ ++#define PNOR_NAND_SEL_REG_OVERRIDE_GH 0 ++#define PNOR_NAND_SEL_REG_PNOR_SEL_GH 1 ++#define PNOR_DIRECT_CMD_OFFSET 0x10 ++#define PNOR_SET_OPMODE_OFFSET 0X18 ++ ++ ++#define IPROC_STRAP_BOOT_DEV_NAND 1 ++#define IPROC_STRAP_BOOT_DEV_PNOR 4 ++#define ICFG_PNOR_STRAPS__PNOR_SRAM_MW_R 0 ++#define PNOR_set_opmode__set_mw_R 0 ++#define PNOR_direct_cmd__cmd_type_R 21 ++#define IPROC_DMU_STRAPS_OFFSET 0x28 ++#define IPROC_BOOT_STRAP_MASK 0x7 ++#if defined(CONFIG_MACH_HR2) || defined(CONFIG_MACH_GH) ++#define IPROC_STRAP_BOOT_DEV_SHIFT 9 ++#elif defined(CONFIG_MACH_GH2) || defined(CONFIG_MACH_SB2) || \ ++ defined(CONFIG_MACH_HR3) ++#define IPROC_STRAP_BOOT_DEV_SHIFT 10 ++#endif ++ ++ ++static struct mtd_info *nor_mtd; ++ ++static struct map_info s29gl_map = { ++ .name = "S29GL", ++ .bankwidth = 4, ++}; ++ ++ ++/* ++ * Initialize FLASH support ++ */ ++static int __init s29gl_mtd_init(void) ++{ ++ struct device_node *np; ++ void __iomem *reg_addr; ++#ifdef CONFIG_MACH_IPROC_P7 ++ void __iomem *reg_strap; ++#endif ++ void __iomem *nor_enable=NULL; ++ struct platform_device *pdev; ++ struct resource *memres; ++ struct mtd_part_parser_data ppdata; ++ u32 straps, val; ++ ++ np = of_find_compatible_node(NULL, NULL, IPROC_NOR_COMPATIBLE); ++ if (!np) { ++ printk(KERN_INFO "No NOR flash controller enabled in DT\n"); ++ return -ENODEV; ++ } ++ ++ if (!of_device_is_available(np)) { ++ printk(KERN_INFO "NOR flash controller disabled in DT\n"); ++ return -ENODEV; ++ } ++ ++ reg_addr = of_iomap(np, 0); ++ if (!reg_addr) { ++ printk(KERN_ERR "NOR base addr ioremap eror\n"); ++ return -EIO; ++ } ++ ++ nor_enable = of_iomap(np, 2); ++ if (!nor_enable) { ++ printk(KERN_ERR "PNOR sel ioremap eror\n"); ++ return -EIO; ++ } ++ ++ /* Check boot device */ ++ straps = readl(get_iproc_dmu_pcu_base() + IPROC_DMU_STRAPS_OFFSET); ++ straps = (straps >> IPROC_STRAP_BOOT_DEV_SHIFT) & IPROC_BOOT_STRAP_MASK; ++ ++ if (straps == IPROC_STRAP_BOOT_DEV_NAND) { ++ /* If booting from NAND, PNOR cannot be used */ ++ return -ENODEV; ++ } else if (straps != IPROC_STRAP_BOOT_DEV_PNOR) { ++ /* Switching to PNOR only if not booting from PNOR */ ++ val = readl_relaxed(nor_enable); ++ if (of_find_compatible_node(NULL, NULL, "brcm,hurricane2")) { ++ val |= (1UL << PNOR_NAND_SEL_REG_OVERRIDE_HR2) | ++ (1UL << PNOR_NAND_SEL_REG_PNOR_SEL_HR2); ++ } else { ++ val |= (1UL << PNOR_NAND_SEL_REG_OVERRIDE_GH) | ++ (1UL << PNOR_NAND_SEL_REG_PNOR_SEL_GH); ++ } ++ writel_relaxed(val, nor_enable); ++ ++#ifdef CONFIG_MACH_IPROC_P7 ++ /* Configure controller memory width based on strap */ ++ reg_strap = of_iomap(np, 3); ++ if (!reg_strap) { ++ printk(KERN_ERR "NOR strap addr ioremap eror\n"); ++ return -EIO; ++ } ++ straps = readl_relaxed(reg_strap) & ++ (1 << ICFG_PNOR_STRAPS__PNOR_SRAM_MW_R); ++ if (straps) { ++ /* 16-bit */ ++ val = readl_relaxed ((void * __iomem) ++ (reg_addr + PNOR_SET_OPMODE_OFFSET)); ++ val |= (1 << PNOR_set_opmode__set_mw_R); ++ writel_relaxed(val, (void * __iomem)( ++ reg_addr + PNOR_SET_OPMODE_OFFSET)); ++ } else { ++ /* 8-bit */ ++ val = readl_relaxed((void * __iomem) ++ (reg_addr + PNOR_SET_OPMODE_OFFSET)); ++ val &= ~(1 << PNOR_set_opmode__set_mw_R); ++ writel_relaxed(val, (void * __iomem) ++ (reg_addr + PNOR_SET_OPMODE_OFFSET)); ++ } ++ val = readl_relaxed((void * __iomem)(reg_addr + ++ PNOR_DIRECT_CMD_OFFSET)); ++ val |= (2 << PNOR_direct_cmd__cmd_type_R); ++ writel_relaxed(val, (void * __iomem)(reg_addr + ++ PNOR_DIRECT_CMD_OFFSET)); ++#endif ++ } ++ ++ printk(KERN_INFO "S29GL-MTD: NOR_INTERFACE Enabled\n"); ++ ++ udelay(1000); ++ ++ pdev = of_find_device_by_node(np); ++ memres = platform_get_resource(pdev, IORESOURCE_MEM, 1); ++ s29gl_map.phys = memres->start; ++ s29gl_map.size = resource_size(memres); ++ s29gl_map.virt = ioremap(s29gl_map.phys, s29gl_map.size); ++ ++ if (!s29gl_map.virt) { ++ printk(KERN_ERR "S29GL-MTD: ioremap failed\n"); ++ if (nor_enable) { ++ /* revert to NAND mode */ ++ val = readl_relaxed(nor_enable); ++ if (of_find_compatible_node(NULL, NULL, ++ "brcm,hurricane2")) ++ val &= ~(1UL << PNOR_NAND_SEL_REG_PNOR_SEL_HR2); ++ else ++ val &= ~(1UL << PNOR_NAND_SEL_REG_PNOR_SEL_GH); ++ writel_relaxed(val, nor_enable); ++ } ++ return -EIO; ++ } ++ ++ simple_map_init(&s29gl_map); ++ ++ // Probe for flash bankwidth 4 ++ printk (KERN_INFO "S29GL-MTD probing 32bit FLASH\n"); ++ nor_mtd = do_map_probe("cfi_probe", &s29gl_map); ++ if (!nor_mtd) { ++ printk (KERN_INFO "S29GL-MTD probing 16bit FLASH\n"); ++ // Probe for bankwidth 2 ++ s29gl_map.bankwidth = 2; ++ nor_mtd = do_map_probe("cfi_probe", &s29gl_map); ++ } ++ ++ if (nor_mtd) { ++ nor_mtd->owner = THIS_MODULE; ++ ppdata.of_node = np; ++ mtd_device_parse_register(nor_mtd, NULL, &ppdata, NULL, 0); ++ printk (KERN_INFO "S29GL-MTD MTD partitions parsed!\n"); ++ return 0; ++ } ++ ++ printk (KERN_INFO "S29GL-MTD NO FLASH found!\n"); ++ if (nor_enable) { ++ /* revert to NAND mode */ ++ val = readl_relaxed(nor_enable); ++ if (of_find_compatible_node(NULL, NULL, "brcm,hurricane2")) ++ val &= ~(1UL << PNOR_NAND_SEL_REG_PNOR_SEL_HR2); ++ else ++ val &= ~(1UL << PNOR_NAND_SEL_REG_PNOR_SEL_GH); ++ writel_relaxed(val, nor_enable); ++ } ++ iounmap((void *)s29gl_map.virt); ++ return -ENXIO; ++} ++ ++/* ++ * Cleanup ++ */ ++static void __exit s29gl_mtd_cleanup(void) ++{ ++ if (nor_mtd) { ++ mtd_device_unregister(nor_mtd); ++ map_destroy(nor_mtd); ++ } ++ ++ if (s29gl_map.virt) { ++ iounmap((void *)s29gl_map.virt); ++ s29gl_map.virt = 0; ++ } ++} ++ ++ ++module_init(s29gl_mtd_init); ++module_exit(s29gl_mtd_cleanup); ++ ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("MTD map driver for Hurricane2 Deerhound evaluation boards"); +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig +--- a/drivers/mtd/nand/Kconfig 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/mtd/nand/Kconfig 2017-11-09 17:53:42.777285000 +0800 +@@ -399,6 +399,17 @@ config MTD_NAND_BRCMNAND + originally designed for Set-Top Box but is used on various BCM7xxx, + BCM3xxx, BCM63xxx, iProc/Cygnus and more. + ++if MTD_NAND_BRCMNAND ++config MTD_NAND_XGS_IPROC ++ bool "XGS iProc NAND controller" ++ depends on ARCH_XGS_IPROC ++ default n ++ help ++ Enable XGS iProc NAND controller. ++ ++ If unsure, say N. ++endif # MTD_NAND_BRCMNAND ++ + config MTD_NAND_BCM47XXNFLASH + tristate "Support for NAND flash on BCM4706 BCMA bus" + depends on BCMA_NFLASH +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c +--- a/drivers/mtd/nand/brcmnand/brcmnand.c 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/mtd/nand/brcmnand/brcmnand.c 2017-11-09 17:53:42.804318000 +0800 +@@ -14,7 +14,7 @@ + #include + #include + #include +-#include ++/*#include */ + #include + #include + #include +@@ -26,7 +26,7 @@ + #include + #include + #include +-#include ++/*#include */ + #include + #include + #include +@@ -1053,8 +1053,16 @@ static void brcmnand_send_cmd(struct brc + ctrl->cmd_pending = cmd; + + intfc = brcmnand_read_reg(ctrl, BRCMNAND_INTFC_STATUS); ++ /* Currently one DTS file supports both NAND and PNOR flash, ++ * but not both controllers can be activated at the same time. ++ * The strap pin on board determines either NAND or PNOR flash ++ * controller is active. Need to comment out the following checking ++ * of NAND controller ready, otherwise it will fail as actually the ++ * NAND controller might be disabled. ++ */ ++#if !defined (CONFIG_MTD_NAND_XGS_IPROC) + BUG_ON(!(intfc & INTFC_CTLR_READY)); +- ++#endif + mb(); /* flush previous writes */ + brcmnand_write_reg(ctrl, BRCMNAND_CMD_START, + cmd << brcmnand_cmd_shift(ctrl)); +@@ -1282,9 +1290,20 @@ static uint8_t brcmnand_read_byte(struct + if (host->last_byte > 0 && offs == 0) + chip->cmdfunc(mtd, NAND_CMD_RNDOUT, addr, -1); + ++ /* For XGS iproc, no byte swap needed for little-endian mode */ ++#if defined (CONFIG_MTD_NAND_XGS_IPROC) ++ if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) ++ ret = ctrl->flash_cache[offs >> 2] >> ++ (24 - ((offs & 0x03) << 3)); ++ else ++ ret = ctrl->flash_cache[offs >> 2] >> ++ ((offs & 0x03) << 3); ++#else + ret = ctrl->flash_cache[offs >> 2] >> + (24 - ((offs & 0x03) << 3)); ++#endif + break; ++ + case NAND_CMD_GET_FEATURES: + if (host->last_byte >= ONFI_SUBFEATURE_PARAM_LEN) { + ret = 0; +@@ -1483,6 +1502,56 @@ static int brcmnand_read_by_pio(struct m + return ret; + } + ++/* ++ * Check a page to see if it is erased (w/ bitflips) after an uncorrectable ECC ++ * error ++ * ++ * Because the HW ECC signals an ECC error if an erase paged has even a single ++ * bitflip, we must check each ECC error to see if it is actually an erased ++ * page with bitflips, not a truly corrupted page. ++ * ++ * On a real error, return a negative error code (-EBADMSG for ECC error), and ++ * buf will contain raw data. ++ * Otherwise, buf gets filled with 0xffs and return the maximum number of ++ * bitflips-per-ECC-sector to the caller. ++ * ++ */ ++static int brcmstb_nand_verify_erased_page(struct mtd_info *mtd, ++ struct nand_chip *chip, void *buf, u64 addr) ++{ ++ int i, sas; ++ void *oob = chip->oob_poi; ++ int bitflips = 0; ++ int page = addr >> chip->page_shift; ++ int ret; ++ ++ if (!buf) { ++ buf = chip->buffers->databuf; ++ /* Invalidate page cache */ ++ chip->pagebuf = -1; ++ } ++ ++ sas = mtd->oobsize / chip->ecc.steps; ++ ++ /* read without ecc for verification */ ++ chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page); ++ ret = chip->ecc.read_page_raw(mtd, chip, buf, true, page); ++ if (ret) ++ return ret; ++ ++ for (i = 0; i < chip->ecc.steps; i++, oob += sas) { ++ ret = nand_check_erased_ecc_chunk(buf, chip->ecc.size, ++ oob, sas, NULL, 0, ++ chip->ecc.strength); ++ if (ret < 0) ++ return ret; ++ ++ bitflips = max(bitflips, ret); ++ } ++ ++ return bitflips; ++} ++ + static int brcmnand_read(struct mtd_info *mtd, struct nand_chip *chip, + u64 addr, unsigned int trans, u32 *buf, u8 *oob) + { +@@ -1513,6 +1582,18 @@ static int brcmnand_read(struct mtd_info + } + + if (mtd_is_eccerr(err)) { ++ /* ++ * Controller version 7.2 has hw encoder to detect erased page ++ * bitflips, apply sw verification for older controllers only ++ */ ++ if (ctrl->nand_version < 0x0702) { ++ err = brcmstb_nand_verify_erased_page(mtd, chip, buf, ++ addr); ++ /* erased page bitflips corrected */ ++ if (err >= 0) ++ return err; ++ } ++ + dev_dbg(ctrl->dev, "uncorrectable error at 0x%llx\n", + (unsigned long long)err_addr); + mtd->ecc_stats.failed++; +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig +--- a/drivers/mtd/spi-nor/Kconfig 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/mtd/spi-nor/Kconfig 2017-11-09 17:53:42.932285000 +0800 +@@ -42,3 +42,38 @@ config SPI_NXP_SPIFI + controller and want to access the Flash as a mtd device. + + endif # MTD_SPI_NOR ++ ++ ++menuconfig MTD_SPI_NOR_IPROC ++ tristate "BRCM IPROC SPI-NOR device support" ++ depends on MTD ++ help ++ This is the framework for the SPI NOR which can be used by the SPI ++ device drivers and the SPI-NOR device driver. ++ ++if MTD_SPI_NOR_IPROC ++ ++config M25PXX_STAY_IN_3BYTE_MODE ++ bool "Stay in 3-byte address mode when idle" ++ default n ++ help ++ This option forces the flash to stay in 3-byte address mode when idle ++ (even for flashes that require 4-byte address). This is work around the ++ reset problem if the controller cannot issue 4-byte OPCODE when booting. ++ ++endif # MTD_SPI_NOR_IPROC ++ ++config MTD_SPI_NOR_USE_4K_SECTORS ++ bool "Use small 4096 B erase sectors" ++ default n ++ help ++ Many flash memories support erasing small (4096 B) sectors. Depending ++ on the usage this feature may provide performance gain in comparison ++ to erasing whole blocks (32/64 KiB). ++ Changing a small part of the flash's contents is usually faster with ++ small sectors. On the other hand erasing should be faster when using ++ 64 KiB block instead of 16 × 4 KiB sectors. ++ ++ Please note that some tools/drivers/filesystems may not work with ++ 4096 B erase size (e.g. UBIFS requires 15 KiB as a minimum). ++ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile +--- a/drivers/mtd/spi-nor/Makefile 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/mtd/spi-nor/Makefile 2017-11-09 17:53:42.933281000 +0800 +@@ -1,3 +1,5 @@ + obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o ++obj-$(CONFIG_MTD_SPI_NOR_IPROC) += spi-nor-iproc.o + obj-$(CONFIG_SPI_FSL_QUADSPI) += fsl-quadspi.o + obj-$(CONFIG_SPI_NXP_SPIFI) += nxp-spifi.o ++ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/mtd/spi-nor/spi-nor-iproc.c b/drivers/mtd/spi-nor/spi-nor-iproc.c +--- a/drivers/mtd/spi-nor/spi-nor-iproc.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/mtd/spi-nor/spi-nor-iproc.c 2017-11-09 17:53:42.936293000 +0800 +@@ -0,0 +1,1467 @@ ++/* ++ Based on spi-nor.c ++ ++ * This code is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++/* Define max times to check status register before we give up. */ ++ ++/* ++ * For everything but full-chip erase; probably could be much smaller, but kept ++ * around for safety for now ++ */ ++#define DEFAULT_READY_WAIT_JIFFIES (40UL * HZ) ++ ++/* ++ * For full-chip erase, calibrated to a 2MB flash (M25P16); should be scaled up ++ * for larger flash ++ */ ++#define CHIP_ERASE_2MB_READY_WAIT_JIFFIES (40UL * HZ) ++ ++#define SPI_NOR_MAX_ID_LEN 6 ++ ++struct flash_info { ++ char *name; ++ ++ /* ++ * This array stores the ID bytes. ++ * The first three bytes are the JEDIC ID. ++ * JEDEC ID zero means "no ID" (mostly older chips). ++ */ ++ u8 id[SPI_NOR_MAX_ID_LEN]; ++ u8 id_len; ++ ++ /* The size listed here is what works with SPINOR_OP_SE, which isn't ++ * necessarily called a "sector" by the vendor. ++ */ ++ unsigned sector_size; ++ u16 n_sectors; ++ ++ u16 page_size; ++ u16 addr_width; ++ ++ u16 flags; ++#define SECT_4K 0x01 /* SPINOR_OP_BE_4K works uniformly */ ++#define SPI_NOR_NO_ERASE 0x02 /* No erase command needed */ ++#define SST_WRITE 0x04 /* use SST byte programming */ ++#define SPI_NOR_NO_FR 0x08 /* Can't do fastread */ ++#define SECT_4K_PMC 0x10 /* SPINOR_OP_BE_4K_PMC works uniformly */ ++#define SPI_NOR_DUAL_READ 0x20 /* Flash supports Dual Read */ ++#define SPI_NOR_QUAD_READ 0x40 /* Flash supports Quad Read */ ++#define USE_FSR 0x80 /* use flag status register */ ++}; ++ ++#define JEDEC_MFR(info) ((info)->id[0]) ++ ++static const struct flash_info *spi_nor_match_id(const char *name); ++ ++/* ++ * Read the status register, returning its value in the location ++ * Return the status register value. ++ * Returns negative if error occurred. ++ */ ++static int read_sr(struct spi_nor *nor) ++{ ++ int ret; ++ u8 val; ++ ++ ret = nor->read_reg(nor, SPINOR_OP_RDSR, &val, 1); ++ if (ret < 0) { ++ pr_err("error %d reading SR\n", (int) ret); ++ return ret; ++ } ++ ++ return val; ++} ++ ++/* ++ * Read the flag status register, returning its value in the location ++ * Return the status register value. ++ * Returns negative if error occurred. ++ */ ++static int read_fsr(struct spi_nor *nor) ++{ ++ int ret; ++ u8 val; ++ ++ ret = nor->read_reg(nor, SPINOR_OP_RDFSR, &val, 1); ++ if (ret < 0) { ++ pr_err("error %d reading FSR\n", ret); ++ return ret; ++ } ++ ++ return val; ++} ++ ++/* ++ * Read configuration register, returning its value in the ++ * location. Return the configuration register value. ++ * Returns negative if error occured. ++ */ ++static int read_cr(struct spi_nor *nor) ++{ ++ int ret; ++ u8 val; ++ ++ ret = nor->read_reg(nor, SPINOR_OP_RDCR, &val, 1); ++ if (ret < 0) { ++ dev_err(nor->dev, "error %d reading CR\n", ret); ++ return ret; ++ } ++ ++ return val; ++} ++ ++/* ++ * Dummy Cycle calculation for different type of read. ++ * It can be used to support more commands with ++ * different dummy cycle requirements. ++ */ ++static inline int spi_nor_read_dummy_cycles(struct spi_nor *nor) ++{ ++ switch (nor->flash_read) { ++ case SPI_NOR_FAST: ++ case SPI_NOR_DUAL: ++ case SPI_NOR_QUAD: ++ return 8; ++ case SPI_NOR_NORMAL: ++ return 0; ++ } ++ return 0; ++} ++ ++/* ++ * Write status register 1 byte ++ * Returns negative if error occurred. ++ */ ++static inline int write_sr(struct spi_nor *nor, u8 val) ++{ ++ nor->cmd_buf[0] = val; ++ return nor->write_reg(nor, SPINOR_OP_WRSR, nor->cmd_buf, 1); ++} ++ ++/* ++ * Set write enable latch with Write Enable command. ++ * Returns negative if error occurred. ++ */ ++static inline int write_enable(struct spi_nor *nor) ++{ ++ return nor->write_reg(nor, SPINOR_OP_WREN, NULL, 0); ++} ++ ++/* ++ * Send write disble instruction to the chip. ++ */ ++static inline int write_disable(struct spi_nor *nor) ++{ ++ return nor->write_reg(nor, SPINOR_OP_WRDI, NULL, 0); ++} ++ ++static inline struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd) ++{ ++ return mtd->priv; ++} ++ ++/* Enable/disable 4-byte addressing mode. */ ++static inline int set_4byte(struct spi_nor *nor, const struct flash_info *info, ++ int enable) ++{ ++ int status; ++ bool need_wren = false; ++ u8 cmd; ++ ++ switch (JEDEC_MFR(info)) { ++ case SNOR_MFR_MICRON: ++ /* Some Micron need WREN command; all will accept it */ ++ need_wren = true; ++ case SNOR_MFR_MACRONIX: ++ case SNOR_MFR_WINBOND: ++ if (need_wren) ++ write_enable(nor); ++ ++ cmd = enable ? SPINOR_OP_EN4B : SPINOR_OP_EX4B; ++ status = nor->write_reg(nor, cmd, NULL, 0); ++ if (need_wren) ++ write_disable(nor); ++ ++ return status; ++ default: ++ /* Spansion style */ ++ nor->cmd_buf[0] = enable << 7; ++ return nor->write_reg(nor, SPINOR_OP_BRWR, nor->cmd_buf, 1); ++ } ++} ++static inline int spi_nor_sr_ready(struct spi_nor *nor) ++{ ++ int sr = read_sr(nor); ++ if (sr < 0) ++ return sr; ++ else ++ return !(sr & SR_WIP); ++} ++ ++static inline int spi_nor_fsr_ready(struct spi_nor *nor) ++{ ++ int fsr = read_fsr(nor); ++ if (fsr < 0) ++ return fsr; ++ else ++ return fsr & FSR_READY; ++} ++ ++static int spi_nor_ready(struct spi_nor *nor) ++{ ++ int sr, fsr; ++ sr = spi_nor_sr_ready(nor); ++ if (sr < 0) ++ return sr; ++ fsr = nor->flags & SNOR_F_USE_FSR ? spi_nor_fsr_ready(nor) : 1; ++ if (fsr < 0) ++ return fsr; ++ return sr && fsr; ++} ++ ++/* ++ * Service routine to read status register until ready, or timeout occurs. ++ * Returns non-zero if error. ++ */ ++static int spi_nor_wait_till_ready_with_timeout(struct spi_nor *nor, ++ unsigned long timeout_jiffies) ++{ ++ unsigned long deadline; ++ int timeout = 0, ret; ++ ++ deadline = jiffies + timeout_jiffies; ++ ++ while (!timeout) { ++ if (time_after_eq(jiffies, deadline)) ++ timeout = 1; ++ ++ ret = spi_nor_ready(nor); ++ if (ret < 0) ++ return ret; ++ if (ret) ++ return 0; ++ ++ cond_resched(); ++ } ++ ++ dev_err(nor->dev, "flash operation timed out\n"); ++ ++ return -ETIMEDOUT; ++} ++ ++static int spi_nor_wait_till_ready(struct spi_nor *nor) ++{ ++ return spi_nor_wait_till_ready_with_timeout(nor, ++ DEFAULT_READY_WAIT_JIFFIES); ++} ++ ++/* ++ * Erase the whole flash memory ++ * ++ * Returns 0 if successful, non-zero otherwise. ++ */ ++static int erase_chip(struct spi_nor *nor) ++{ ++ dev_dbg(nor->dev, " %lldKiB\n", (long long)(nor->mtd.size >> 10)); ++ ++ return nor->write_reg(nor, SPINOR_OP_CHIP_ERASE, NULL, 0); ++} ++ ++static int spi_nor_lock_and_prep(struct spi_nor *nor, enum spi_nor_ops ops) ++{ ++ int ret = 0; ++ ++ mutex_lock(&nor->lock); ++ ++ if (nor->prepare) { ++ ret = nor->prepare(nor, ops); ++ if (ret) { ++ dev_err(nor->dev, "failed in the preparation.\n"); ++ mutex_unlock(&nor->lock); ++ return ret; ++ } ++ } ++ return ret; ++} ++ ++static void spi_nor_unlock_and_unprep(struct spi_nor *nor, enum spi_nor_ops ops) ++{ ++ if (nor->unprepare) ++ nor->unprepare(nor, ops); ++ mutex_unlock(&nor->lock); ++} ++ ++/* ++ * Erase an address range on the nor chip. The address range may extend ++ * one or more erase sectors. Return an error is there is a problem erasing. ++ */ ++static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) ++{ ++ struct spi_nor *nor = mtd_to_spi_nor(mtd); ++ u32 addr, len; ++ uint32_t rem; ++ int ret; ++ ++ dev_dbg(nor->dev, "at 0x%llx, len %lld\n", (long long)instr->addr, ++ (long long)instr->len); ++ ++ div_u64_rem(instr->len, mtd->erasesize, &rem); ++ if (rem) ++ return -EINVAL; ++ ++ addr = instr->addr; ++ len = instr->len; ++ ++ ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_ERASE); ++ if (ret) ++ return ret; ++ ++ /* whole-chip erase? */ ++ if (len == mtd->size) { ++ unsigned long timeout; ++ ++ write_enable(nor); ++ ++ if (erase_chip(nor)) { ++ ret = -EIO; ++ goto erase_err; ++ } ++ ++ /* ++ * Scale the timeout linearly with the size of the flash, with ++ * a minimum calibrated to an old 2MB flash. We could try to ++ * pull these from CFI/SFDP, but these values should be good ++ * enough for now. ++ */ ++ timeout = max(CHIP_ERASE_2MB_READY_WAIT_JIFFIES, ++ CHIP_ERASE_2MB_READY_WAIT_JIFFIES * ++ (unsigned long)(mtd->size / SZ_2M)); ++ ret = spi_nor_wait_till_ready_with_timeout(nor, timeout); ++ if (ret) ++ goto erase_err; ++ ++ /* REVISIT in some cases we could speed up erasing large regions ++ * by using SPINOR_OP_SE instead of SPINOR_OP_BE_4K. We may have set up ++ * to use "small sector erase", but that's not always optimal. ++ */ ++ ++ /* "sector"-at-a-time erase */ ++ } else { ++ while (len) { ++#ifdef CONFIG_M25PXX_STAY_IN_3BYTE_MODE ++ /* Set to 4-byte mode if addr >= 16M */ ++ /* Note: set_4byte will call write_disable for Micron flash, so set_4byte should be called before the following write_enable(nor) */ ++ if ( addr >= 0x1000000 ) ++ set_4byte(nor, nor->priv1, 1); ++#endif /* CONFIG_M25PXX_STAY_IN_3BYTE_MODE */ ++ ++ write_enable(nor); ++ ++ if (nor->erase(nor, addr)) { ++ ret = -EIO; ++ goto erase_err; ++ } ++ ++ addr += mtd->erasesize; ++ len -= mtd->erasesize; ++ ++ ret = spi_nor_wait_till_ready(nor); ++ if (ret) ++ goto erase_err; ++ } ++ } ++ ++#ifdef CONFIG_M25PXX_STAY_IN_3BYTE_MODE ++ /* Reset to 3-byte mode if it was set to 4-byte mode */ ++ if (addr >= 0x1000000) { ++ spi_nor_wait_till_ready(nor); ++ set_4byte(nor, nor->priv1, 0); ++ } ++#endif /* CONFIG_M25PXX_STAY_IN_3BYTE_MODE */ ++ ++ write_disable(nor); ++ ++ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE); ++ ++ instr->state = MTD_ERASE_DONE; ++ mtd_erase_callback(instr); ++ ++ return ret; ++ ++erase_err: ++ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE); ++ instr->state = MTD_ERASE_FAILED; ++ return ret; ++} ++ ++static void stm_get_locked_range(struct spi_nor *nor, u8 sr, loff_t *ofs, ++ uint64_t *len) ++{ ++ struct mtd_info *mtd = &nor->mtd; ++ u8 mask = SR_BP2 | SR_BP1 | SR_BP0; ++ int shift = ffs(mask) - 1; ++ int pow; ++ ++ if (!(sr & mask)) { ++ /* No protection */ ++ *ofs = 0; ++ *len = 0; ++ } else { ++ pow = ((sr & mask) ^ mask) >> shift; ++ *len = mtd->size >> pow; ++ *ofs = mtd->size - *len; ++ } ++} ++ ++/* ++ * Return 1 if the entire region is locked, 0 otherwise ++ */ ++static int stm_is_locked_sr(struct spi_nor *nor, loff_t ofs, uint64_t len, ++ u8 sr) ++{ ++ loff_t lock_offs; ++ uint64_t lock_len; ++ ++ stm_get_locked_range(nor, sr, &lock_offs, &lock_len); ++ ++ return (ofs + len <= lock_offs + lock_len) && (ofs >= lock_offs); ++} ++ ++/* ++ * Lock a region of the flash. Compatible with ST Micro and similar flash. ++ * Supports only the block protection bits BP{0,1,2} in the status register ++ * (SR). Does not support these features found in newer SR bitfields: ++ * - TB: top/bottom protect - only handle TB=0 (top protect) ++ * - SEC: sector/block protect - only handle SEC=0 (block protect) ++ * - CMP: complement protect - only support CMP=0 (range is not complemented) ++ * ++ * Sample table portion for 8MB flash (Winbond w25q64fw): ++ * ++ * SEC | TB | BP2 | BP1 | BP0 | Prot Length | Protected Portion ++ * -------------------------------------------------------------------------- ++ * X | X | 0 | 0 | 0 | NONE | NONE ++ * 0 | 0 | 0 | 0 | 1 | 128 KB | Upper 1/64 ++ * 0 | 0 | 0 | 1 | 0 | 256 KB | Upper 1/32 ++ * 0 | 0 | 0 | 1 | 1 | 512 KB | Upper 1/16 ++ * 0 | 0 | 1 | 0 | 0 | 1 MB | Upper 1/8 ++ * 0 | 0 | 1 | 0 | 1 | 2 MB | Upper 1/4 ++ * 0 | 0 | 1 | 1 | 0 | 4 MB | Upper 1/2 ++ * X | X | 1 | 1 | 1 | 8 MB | ALL ++ * ++ * Returns negative on errors, 0 on success. ++ */ ++static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len) ++{ ++ struct mtd_info *mtd = &nor->mtd; ++ u8 status_old, status_new; ++ u8 mask = SR_BP2 | SR_BP1 | SR_BP0; ++ u8 shift = ffs(mask) - 1, pow, val; ++ ++ status_old = read_sr(nor); ++ ++ /* SPI NOR always locks to the end */ ++ if (ofs + len != mtd->size) { ++ /* Does combined region extend to end? */ ++ if (!stm_is_locked_sr(nor, ofs + len, mtd->size - ofs - len, ++ status_old)) ++ return -EINVAL; ++ len = mtd->size - ofs; ++ } ++ ++ /* ++ * Need smallest pow such that: ++ * ++ * 1 / (2^pow) <= (len / size) ++ * ++ * so (assuming power-of-2 size) we do: ++ * ++ * pow = ceil(log2(size / len)) = log2(size) - floor(log2(len)) ++ */ ++ pow = ilog2(mtd->size) - ilog2(len); ++ val = mask - (pow << shift); ++ if (val & ~mask) ++ return -EINVAL; ++ /* Don't "lock" with no region! */ ++ if (!(val & mask)) ++ return -EINVAL; ++ ++ status_new = (status_old & ~mask) | val; ++ ++ /* Only modify protection if it will not unlock other areas */ ++ if ((status_new & mask) <= (status_old & mask)) ++ return -EINVAL; ++ ++ write_enable(nor); ++ return write_sr(nor, status_new); ++} ++ ++/* ++ * Unlock a region of the flash. See stm_lock() for more info ++ * ++ * Returns negative on errors, 0 on success. ++ */ ++static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len) ++{ ++ struct mtd_info *mtd = &nor->mtd; ++ uint8_t status_old, status_new; ++ u8 mask = SR_BP2 | SR_BP1 | SR_BP0; ++ u8 shift = ffs(mask) - 1, pow, val; ++ ++ status_old = read_sr(nor); ++ ++ /* Cannot unlock; would unlock larger region than requested */ ++ if (stm_is_locked_sr(nor, ofs - mtd->erasesize, mtd->erasesize, ++ status_old)) ++ return -EINVAL; ++ ++ /* ++ * Need largest pow such that: ++ * ++ * 1 / (2^pow) >= (len / size) ++ * ++ * so (assuming power-of-2 size) we do: ++ * ++ * pow = floor(log2(size / len)) = log2(size) - ceil(log2(len)) ++ */ ++ pow = ilog2(mtd->size) - order_base_2(mtd->size - (ofs + len)); ++ if (ofs + len == mtd->size) { ++ val = 0; /* fully unlocked */ ++ } else { ++ val = mask - (pow << shift); ++ /* Some power-of-two sizes are not supported */ ++ if (val & ~mask) ++ return -EINVAL; ++ } ++ ++ status_new = (status_old & ~mask) | val; ++ ++ /* Only modify protection if it will not lock other areas */ ++ if ((status_new & mask) >= (status_old & mask)) ++ return -EINVAL; ++ ++ write_enable(nor); ++ return write_sr(nor, status_new); ++} ++ ++/* ++ * Check if a region of the flash is (completely) locked. See stm_lock() for ++ * more info. ++ * ++ * Returns 1 if entire region is locked, 0 if any portion is unlocked, and ++ * negative on errors. ++ */ ++static int stm_is_locked(struct spi_nor *nor, loff_t ofs, uint64_t len) ++{ ++ int status; ++ ++ status = read_sr(nor); ++ if (status < 0) ++ return status; ++ ++ return stm_is_locked_sr(nor, ofs, len, status); ++} ++ ++static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) ++{ ++ struct spi_nor *nor = mtd_to_spi_nor(mtd); ++ int ret; ++ ++ ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_LOCK); ++ if (ret) ++ return ret; ++ ++ ret = nor->flash_lock(nor, ofs, len); ++ ++ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_UNLOCK); ++ return ret; ++} ++ ++static int spi_nor_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) ++{ ++ struct spi_nor *nor = mtd_to_spi_nor(mtd); ++ int ret; ++ ++ ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_UNLOCK); ++ if (ret) ++ return ret; ++ ++ ret = nor->flash_unlock(nor, ofs, len); ++ ++ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK); ++ return ret; ++} ++ ++static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) ++{ ++ struct spi_nor *nor = mtd_to_spi_nor(mtd); ++ int ret; ++ ++ ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_UNLOCK); ++ if (ret) ++ return ret; ++ ++ ret = nor->flash_is_locked(nor, ofs, len); ++ ++ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK); ++ return ret; ++} ++ ++/* Used when the "_ext_id" is two bytes at most */ ++#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ ++ .id = { \ ++ ((_jedec_id) >> 16) & 0xff, \ ++ ((_jedec_id) >> 8) & 0xff, \ ++ (_jedec_id) & 0xff, \ ++ ((_ext_id) >> 8) & 0xff, \ ++ (_ext_id) & 0xff, \ ++ }, \ ++ .id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))), \ ++ .sector_size = (_sector_size), \ ++ .n_sectors = (_n_sectors), \ ++ .page_size = 256, \ ++ .flags = (_flags), ++ ++#define INFO6(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ ++ .id = { \ ++ ((_jedec_id) >> 16) & 0xff, \ ++ ((_jedec_id) >> 8) & 0xff, \ ++ (_jedec_id) & 0xff, \ ++ ((_ext_id) >> 16) & 0xff, \ ++ ((_ext_id) >> 8) & 0xff, \ ++ (_ext_id) & 0xff, \ ++ }, \ ++ .id_len = 6, \ ++ .sector_size = (_sector_size), \ ++ .n_sectors = (_n_sectors), \ ++ .page_size = 256, \ ++ .flags = (_flags), ++ ++#define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_width, _flags) \ ++ .sector_size = (_sector_size), \ ++ .n_sectors = (_n_sectors), \ ++ .page_size = (_page_size), \ ++ .addr_width = (_addr_width), \ ++ .flags = (_flags), ++ ++/* NOTE: double check command sets and memory organization when you add ++ * more nor chips. This current list focusses on newer chips, which ++ * have been converging on command sets which including JEDEC ID. ++ * ++ * All newly added entries should describe *hardware* and should use SECT_4K ++ * (or SECT_4K_PMC) if hardware supports erasing 4 KiB sectors. For usage ++ * scenarios excluding small sectors there is config option that can be ++ * disabled: CONFIG_MTD_SPI_NOR_USE_4K_SECTORS. ++ * For historical (and compatibility) reasons (before we got above config) some ++ * old entries may be missing 4K flag. ++ */ ++static const struct flash_info spi_nor_ids[] = { ++ /* Atmel -- some are (confusingly) marketed as "DataFlash" */ ++ { "at25fs010", INFO(0x1f6601, 0, 32 * 1024, 4, SECT_4K) }, ++ { "at25fs040", INFO(0x1f6604, 0, 64 * 1024, 8, SECT_4K) }, ++ ++ { "at25df041a", INFO(0x1f4401, 0, 64 * 1024, 8, SECT_4K) }, ++ { "at25df321a", INFO(0x1f4701, 0, 64 * 1024, 64, SECT_4K) }, ++ { "at25df641", INFO(0x1f4800, 0, 64 * 1024, 128, SECT_4K) }, ++ ++ { "at26f004", INFO(0x1f0400, 0, 64 * 1024, 8, SECT_4K) }, ++ { "at26df081a", INFO(0x1f4501, 0, 64 * 1024, 16, SECT_4K) }, ++ { "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SECT_4K) }, ++ { "at26df321", INFO(0x1f4700, 0, 64 * 1024, 64, SECT_4K) }, ++ ++ { "at45db081d", INFO(0x1f2500, 0, 64 * 1024, 16, SECT_4K) }, ++ ++ /* EON -- en25xxx */ ++ { "en25f32", INFO(0x1c3116, 0, 64 * 1024, 64, SECT_4K) }, ++ { "en25p32", INFO(0x1c2016, 0, 64 * 1024, 64, 0) }, ++ { "en25q32b", INFO(0x1c3016, 0, 64 * 1024, 64, 0) }, ++ { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) }, ++ { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) }, ++ { "en25qh128", INFO(0x1c7018, 0, 64 * 1024, 256, 0) }, ++ { "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512, 0) }, ++ { "en25s64", INFO(0x1c3817, 0, 64 * 1024, 128, SECT_4K) }, ++ ++ /* ESMT */ ++ { "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64, SECT_4K) }, ++ ++ /* Everspin */ ++ { "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, ++ { "mr25h10", CAT25_INFO(128 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, ++ ++ /* Fujitsu */ ++ { "mb85rs1mt", INFO(0x047f27, 0, 128 * 1024, 1, SPI_NOR_NO_ERASE) }, ++ ++ /* GigaDevice */ ++ { "gd25q32", INFO(0xc84016, 0, 64 * 1024, 64, SECT_4K) }, ++ { "gd25q64", INFO(0xc84017, 0, 64 * 1024, 128, SECT_4K) }, ++ { "gd25q128", INFO(0xc84018, 0, 64 * 1024, 256, SECT_4K) }, ++ ++ /* Intel/Numonyx -- xxxs33b */ ++ { "160s33b", INFO(0x898911, 0, 64 * 1024, 32, 0) }, ++ { "320s33b", INFO(0x898912, 0, 64 * 1024, 64, 0) }, ++ { "640s33b", INFO(0x898913, 0, 64 * 1024, 128, 0) }, ++ ++ /* ISSI */ ++ { "is25cd512", INFO(0x7f9d20, 0, 32 * 1024, 2, SECT_4K) }, ++ ++ /* Macronix */ ++ { "mx25l512e", INFO(0xc22010, 0, 64 * 1024, 1, SECT_4K) }, ++ { "mx25l2005a", INFO(0xc22012, 0, 64 * 1024, 4, SECT_4K) }, ++ { "mx25l4005a", INFO(0xc22013, 0, 64 * 1024, 8, SECT_4K) }, ++ { "mx25l8005", INFO(0xc22014, 0, 64 * 1024, 16, 0) }, ++ { "mx25l1606e", INFO(0xc22015, 0, 64 * 1024, 32, SECT_4K) }, ++ { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, 0) }, ++ { "mx25l3255e", INFO(0xc29e16, 0, 64 * 1024, 64, SECT_4K) }, ++ { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, 0) }, ++ { "mx25u6435f", INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) }, ++ { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) }, ++ { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) }, ++ { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) }, ++ { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) }, ++ { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_QUAD_READ) }, ++ { "mx66l1g55g", INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) }, ++ ++ /* Micron */ ++ { "n25q032", INFO(0x20ba16, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) }, ++ { "n25q032a", INFO(0x20bb16, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) }, ++ { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) }, ++ { "n25q064a", INFO(0x20bb17, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) }, ++ { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, SPI_NOR_QUAD_READ) }, ++ { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, SPI_NOR_QUAD_READ) }, ++ { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ) }, ++ { "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, ++ { "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, ++ { "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, ++ ++ /* PMC */ ++ { "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) }, ++ { "pm25lv010", INFO(0, 0, 32 * 1024, 4, SECT_4K_PMC) }, ++ { "pm25lq032", INFO(0x7f9d46, 0, 64 * 1024, 64, SECT_4K) }, ++ ++ /* Spansion -- single (large) sector size only, at least ++ * for the chips listed here (without boot sectors). ++ */ ++ { "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, ++ { "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, ++ { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) }, ++ { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, ++ { "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, ++ { "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) }, ++ { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) }, ++ { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) }, ++ { "s25fl128s", INFO6(0x012018, 0x4d0180, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) }, ++ { "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, ++ { "s25fl129p1", INFO(0x012018, 0x4d01, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, ++ { "s25sl004a", INFO(0x010212, 0, 64 * 1024, 8, 0) }, ++ { "s25sl008a", INFO(0x010213, 0, 64 * 1024, 16, 0) }, ++ { "s25sl016a", INFO(0x010214, 0, 64 * 1024, 32, 0) }, ++ { "s25sl032a", INFO(0x010215, 0, 64 * 1024, 64, 0) }, ++ { "s25sl064a", INFO(0x010216, 0, 64 * 1024, 128, 0) }, ++ { "s25fl004k", INFO(0xef4013, 0, 64 * 1024, 8, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, ++ { "s25fl008k", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, ++ { "s25fl016k", INFO(0xef4015, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, ++ { "s25fl064k", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, ++ { "s25fl132k", INFO(0x014016, 0, 64 * 1024, 64, SECT_4K) }, ++ { "s25fl164k", INFO(0x014017, 0, 64 * 1024, 128, SECT_4K) }, ++ { "s25fl204k", INFO(0x014013, 0, 64 * 1024, 8, SECT_4K | SPI_NOR_DUAL_READ) }, ++ ++ /* SST -- large erase sizes are "overlays", "sectors" are 4K */ ++ { "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) }, ++ { "sst25vf080b", INFO(0xbf258e, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) }, ++ { "sst25vf016b", INFO(0xbf2541, 0, 64 * 1024, 32, SECT_4K | SST_WRITE) }, ++ { "sst25vf032b", INFO(0xbf254a, 0, 64 * 1024, 64, SECT_4K | SST_WRITE) }, ++ { "sst25vf064c", INFO(0xbf254b, 0, 64 * 1024, 128, SECT_4K) }, ++ { "sst25wf512", INFO(0xbf2501, 0, 64 * 1024, 1, SECT_4K | SST_WRITE) }, ++ { "sst25wf010", INFO(0xbf2502, 0, 64 * 1024, 2, SECT_4K | SST_WRITE) }, ++ { "sst25wf020", INFO(0xbf2503, 0, 64 * 1024, 4, SECT_4K | SST_WRITE) }, ++ { "sst25wf020a", INFO(0x621612, 0, 64 * 1024, 4, SECT_4K) }, ++ { "sst25wf040b", INFO(0x621613, 0, 64 * 1024, 8, SECT_4K) }, ++ { "sst25wf040", INFO(0xbf2504, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) }, ++ { "sst25wf080", INFO(0xbf2505, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) }, ++ { "sst26vf016", INFO(0xbf2601, 0, 64 * 1024, 32, SECT_4K) }, ++ { "sst26vf032", INFO(0xbf2602, 0, 64 * 1024, 64, SECT_4K) }, ++ ++ /* ST Microelectronics -- newer production may have feature updates */ ++ { "m25p05", INFO(0x202010, 0, 32 * 1024, 2, 0) }, ++ { "m25p10", INFO(0x202011, 0, 32 * 1024, 4, 0) }, ++ { "m25p20", INFO(0x202012, 0, 64 * 1024, 4, 0) }, ++ { "m25p40", INFO(0x202013, 0, 64 * 1024, 8, 0) }, ++ { "m25p80", INFO(0x202014, 0, 64 * 1024, 16, 0) }, ++ { "m25p16", INFO(0x202015, 0, 64 * 1024, 32, 0) }, ++ { "m25p32", INFO(0x202016, 0, 64 * 1024, 64, 0) }, ++ { "m25p64", INFO(0x202017, 0, 64 * 1024, 128, 0) }, ++ { "m25p128", INFO(0x202018, 0, 256 * 1024, 64, 0) }, ++ ++ { "m25p05-nonjedec", INFO(0, 0, 32 * 1024, 2, 0) }, ++ { "m25p10-nonjedec", INFO(0, 0, 32 * 1024, 4, 0) }, ++ { "m25p20-nonjedec", INFO(0, 0, 64 * 1024, 4, 0) }, ++ { "m25p40-nonjedec", INFO(0, 0, 64 * 1024, 8, 0) }, ++ { "m25p80-nonjedec", INFO(0, 0, 64 * 1024, 16, 0) }, ++ { "m25p16-nonjedec", INFO(0, 0, 64 * 1024, 32, 0) }, ++ { "m25p32-nonjedec", INFO(0, 0, 64 * 1024, 64, 0) }, ++ { "m25p64-nonjedec", INFO(0, 0, 64 * 1024, 128, 0) }, ++ { "m25p128-nonjedec", INFO(0, 0, 256 * 1024, 64, 0) }, ++ ++ { "m45pe10", INFO(0x204011, 0, 64 * 1024, 2, 0) }, ++ { "m45pe80", INFO(0x204014, 0, 64 * 1024, 16, 0) }, ++ { "m45pe16", INFO(0x204015, 0, 64 * 1024, 32, 0) }, ++ ++ { "m25pe20", INFO(0x208012, 0, 64 * 1024, 4, 0) }, ++ { "m25pe80", INFO(0x208014, 0, 64 * 1024, 16, 0) }, ++ { "m25pe16", INFO(0x208015, 0, 64 * 1024, 32, SECT_4K) }, ++ ++ { "m25px16", INFO(0x207115, 0, 64 * 1024, 32, SECT_4K) }, ++ { "m25px32", INFO(0x207116, 0, 64 * 1024, 64, SECT_4K) }, ++ { "m25px32-s0", INFO(0x207316, 0, 64 * 1024, 64, SECT_4K) }, ++ { "m25px32-s1", INFO(0x206316, 0, 64 * 1024, 64, SECT_4K) }, ++ { "m25px64", INFO(0x207117, 0, 64 * 1024, 128, 0) }, ++ { "m25px80", INFO(0x207114, 0, 64 * 1024, 16, 0) }, ++ ++ /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */ ++ { "w25x05", INFO(0xef3010, 0, 64 * 1024, 1, SECT_4K) }, ++ { "w25x10", INFO(0xef3011, 0, 64 * 1024, 2, SECT_4K) }, ++ { "w25x20", INFO(0xef3012, 0, 64 * 1024, 4, SECT_4K) }, ++ { "w25x40", INFO(0xef3013, 0, 64 * 1024, 8, SECT_4K) }, ++ { "w25x80", INFO(0xef3014, 0, 64 * 1024, 16, SECT_4K) }, ++ { "w25x16", INFO(0xef3015, 0, 64 * 1024, 32, SECT_4K) }, ++ { "w25x32", INFO(0xef3016, 0, 64 * 1024, 64, SECT_4K) }, ++ { "w25q32", INFO(0xef4016, 0, 64 * 1024, 64, SECT_4K) }, ++ { "w25q32dw", INFO(0xef6016, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, ++ { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) }, ++ { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, ++ { "w25q64dw", INFO(0xef6017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, ++ { "w25q128fw", INFO(0xef6018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, ++ { "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) }, ++ { "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) }, ++ { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) }, ++ { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K) }, ++ { "w25m512", INFO(0xef7119, 0, 64 * 1024, 1024, SECT_4K) }, ++ ++ /* Catalyst / On Semiconductor -- non-JEDEC */ ++ { "cat25c11", CAT25_INFO( 16, 8, 16, 1, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, ++ { "cat25c03", CAT25_INFO( 32, 8, 16, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, ++ { "cat25c09", CAT25_INFO( 128, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, ++ { "cat25c17", CAT25_INFO( 256, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, ++ { "cat25128", CAT25_INFO(2048, 8, 64, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, ++ { }, ++}; ++ ++static const struct flash_info *spi_nor_read_id(struct spi_nor *nor) ++{ ++ int tmp; ++ u8 id[SPI_NOR_MAX_ID_LEN]; ++ const struct flash_info *info; ++ ++ tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN); ++ if (tmp < 0) { ++ dev_dbg(nor->dev, " error %d reading JEDEC ID\n", tmp); ++ return ERR_PTR(tmp); ++ } ++ ++ for (tmp = 0; tmp < ARRAY_SIZE(spi_nor_ids) - 1; tmp++) { ++ info = &spi_nor_ids[tmp]; ++ if (info->id_len) { ++ if (!memcmp(info->id, id, info->id_len)) ++ return &spi_nor_ids[tmp]; ++ } ++ } ++ dev_err(nor->dev, "unrecognized JEDEC id bytes: %02x, %2x, %2x\n", ++ id[0], id[1], id[2]); ++ return ERR_PTR(-ENODEV); ++} ++ ++static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len, ++ size_t *retlen, u_char *buf) ++{ ++ struct spi_nor *nor = mtd_to_spi_nor(mtd); ++ int ret; ++ ++ dev_dbg(nor->dev, "from 0x%08x, len %zd\n", (u32)from, len); ++ ++ ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_READ); ++ if (ret) ++ return ret; ++ ++#ifdef CONFIG_M25PXX_STAY_IN_3BYTE_MODE ++ /* set to 4-byte mode */ ++ if (from + len > 0x1000000) ++ set_4byte(nor, nor->priv1, 1); ++#endif /* CONFIG_M25PXX_STAY_IN_3BYTE_MODE */ ++ ++ ret = nor->read(nor, from, len, retlen, buf); ++ ++#ifdef CONFIG_M25PXX_STAY_IN_3BYTE_MODE ++ /* set to 3-byte mode */ ++ if (from + len > 0x1000000) ++ set_4byte(nor, nor->priv1, 0); ++#endif /* CONFIG_M25PXX_STAY_IN_3BYTE_MODE */ ++ ++ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_READ); ++ return ret; ++} ++ ++static int sst_write(struct mtd_info *mtd, loff_t to, size_t len, ++ size_t *retlen, const u_char *buf) ++{ ++ struct spi_nor *nor = mtd_to_spi_nor(mtd); ++ size_t actual; ++ int ret; ++#ifdef CONFIG_M25PXX_STAY_IN_3BYTE_MODE ++ int addr_4byte = 0; ++#endif /* CONFIG_M25PXX_STAY_IN_3BYTE_MODE */ ++ ++ dev_dbg(nor->dev, "to 0x%08x, len %zd\n", (u32)to, len); ++ ++ ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_WRITE); ++ if (ret) ++ return ret; ++ ++#ifdef CONFIG_M25PXX_STAY_IN_3BYTE_MODE ++ /* set to 4-byte mode */ ++ if (to >= 0x1000000) { ++ set_4byte(nor, nor->priv1, 1); ++ addr_4byte = 1; ++ } ++#endif /* CONFIG_M25PXX_STAY_IN_3BYTE_MODE */ ++ ++ write_enable(nor); ++ ++ nor->sst_write_second = false; ++ ++ actual = to % 2; ++ /* Start write from odd address. */ ++ if (actual) { ++ nor->program_opcode = SPINOR_OP_BP; ++ ++ /* write one byte. */ ++ nor->write(nor, to, 1, retlen, buf); ++ ret = spi_nor_wait_till_ready(nor); ++ if (ret) ++ goto time_out; ++ } ++ to += actual; ++ ++#ifdef CONFIG_M25PXX_STAY_IN_3BYTE_MODE ++ /* Use 4-byte mode only if the address is > 16MB */ ++ if (to >= 0x1000000 && !addr_4byte) { ++ set_4byte(nor, nor->priv1, 1); ++ addr_4byte = 1; ++ } ++#endif /* CONFIG_M25PXX_STAY_IN_3BYTE_MODE */ ++ ++ /* Write out most of the data here. */ ++ for (; actual < len - 1; actual += 2) { ++ nor->program_opcode = SPINOR_OP_AAI_WP; ++ ++ /* write two bytes. */ ++ nor->write(nor, to, 2, retlen, buf + actual); ++ ret = spi_nor_wait_till_ready(nor); ++ if (ret) ++ goto time_out; ++ to += 2; ++ nor->sst_write_second = true; ++ } ++ nor->sst_write_second = false; ++ ++ write_disable(nor); ++ ret = spi_nor_wait_till_ready(nor); ++ if (ret) ++ goto time_out; ++ ++ /* Write out trailing byte if it exists. */ ++ if (actual != len) { ++#ifdef CONFIG_M25PXX_STAY_IN_3BYTE_MODE ++ /* Use 4-byte mode only if the address is > 16MB */ ++ if (to >= 0x1000000 && !addr_4byte) { ++ set_4byte(nor, nor->priv1, 1); ++ addr_4byte = 1; ++ } ++#endif /* CONFIG_M25PXX_STAY_IN_3BYTE_MODE */ ++ ++ write_enable(nor); ++ ++ nor->program_opcode = SPINOR_OP_BP; ++ nor->write(nor, to, 1, retlen, buf + actual); ++ ++ ret = spi_nor_wait_till_ready(nor); ++ if (ret) ++ goto time_out; ++ write_disable(nor); ++ } ++ ++#ifdef CONFIG_M25PXX_STAY_IN_3BYTE_MODE ++ /* Reset to 3-byte mode if the address is > 16MB */ ++ if (addr_4byte) ++ set_4byte(nor, nor->priv1, 0); ++#endif /* CONFIG_M25PXX_STAY_IN_3BYTE_MODE */ ++ ++time_out: ++ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_WRITE); ++ return ret; ++} ++ ++/* ++ * Write an address range to the nor chip. Data must be written in ++ * FLASH_PAGESIZE chunks. The address range may be any size provided ++ * it is within the physical boundaries. ++ */ ++static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len, ++ size_t *retlen, const u_char *buf) ++{ ++ struct spi_nor *nor = mtd_to_spi_nor(mtd); ++ u32 page_offset, page_size, i; ++ int ret; ++ ++ dev_dbg(nor->dev, "to 0x%08x, len %zd\n", (u32)to, len); ++ ++ ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_WRITE); ++ if (ret) ++ return ret; ++ ++#ifdef CONFIG_M25PXX_STAY_IN_3BYTE_MODE ++ /* set to 4-byte mode */ ++ /* Note: set_4byte will call write_disable for Micron flash, so set_4byte should be called before the following write_enable(nor) */ ++ if (to >= 0x1000000) ++ set_4byte(nor, nor->priv1, 1); ++#endif /* CONFIG_M25PXX_STAY_IN_3BYTE_MODE */ ++ ++ write_enable(nor); ++ ++ page_offset = to & (nor->page_size - 1); ++ ++ /* do all the bytes fit onto one page? */ ++ if (page_offset + len <= nor->page_size) { ++ nor->write(nor, to, len, retlen, buf); ++ } else { ++ /* the size of data remaining on the first page */ ++ page_size = nor->page_size - page_offset; ++ nor->write(nor, to, page_size, retlen, buf); ++ ++ /* write everything in nor->page_size chunks */ ++ for (i = page_size; i < len; i += page_size) { ++ page_size = len - i; ++ if (page_size > nor->page_size) ++ page_size = nor->page_size; ++ ++ ret = spi_nor_wait_till_ready(nor); ++ if (ret) ++ goto write_err; ++ ++#ifdef CONFIG_M25PXX_STAY_IN_3BYTE_MODE ++ /* set to 4-byte mode if this is the first time > 16MB*/ ++ if ( (to + i - page_size < 0x1000000) && (to + i >= 0x1000000) ) ++ set_4byte(nor, nor->priv1, 1); ++#endif /* CONFIG_M25PXX_STAY_IN_3BYTE_MODE */ ++ ++ write_enable(nor); ++ ++ nor->write(nor, to + i, page_size, retlen, buf + i); ++ } ++ } ++ ++ ret = spi_nor_wait_till_ready(nor); ++ ++#ifdef CONFIG_M25PXX_STAY_IN_3BYTE_MODE ++ /* reset to 3-byte mode*/ ++ if (to + len >= 0x1000000) ++ set_4byte(nor, nor->priv1, 0); ++#endif /* CONFIG_M25PXX_STAY_IN_3BYTE_MODE */ ++ ++write_err: ++ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_WRITE); ++ return ret; ++} ++ ++static int macronix_quad_enable(struct spi_nor *nor) ++{ ++ int ret, val; ++ ++ val = read_sr(nor); ++ write_enable(nor); ++ ++ write_sr(nor, val | SR_QUAD_EN_MX); ++ ++ if (spi_nor_wait_till_ready(nor)) ++ return 1; ++ ++ ret = read_sr(nor); ++ if (!(ret > 0 && (ret & SR_QUAD_EN_MX))) { ++ dev_err(nor->dev, "Macronix Quad bit not set\n"); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++/* ++ * Write status Register and configuration register with 2 bytes ++ * The first byte will be written to the status register, while the ++ * second byte will be written to the configuration register. ++ * Return negative if error occured. ++ */ ++static int write_sr_cr(struct spi_nor *nor, u16 val) ++{ ++ nor->cmd_buf[0] = val & 0xff; ++ nor->cmd_buf[1] = (val >> 8); ++ ++ return nor->write_reg(nor, SPINOR_OP_WRSR, nor->cmd_buf, 2); ++} ++ ++static int spansion_quad_enable(struct spi_nor *nor) ++{ ++ int ret; ++ int quad_en = CR_QUAD_EN_SPAN << 8; ++ ++ write_enable(nor); ++ ++ ret = write_sr_cr(nor, quad_en); ++ if (ret < 0) { ++ dev_err(nor->dev, ++ "error while writing configuration register\n"); ++ return -EINVAL; ++ } ++ ++ /* read back and check it */ ++ ret = read_cr(nor); ++ if (!(ret > 0 && (ret & CR_QUAD_EN_SPAN))) { ++ dev_err(nor->dev, "Spansion Quad bit not set\n"); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int micron_quad_enable(struct spi_nor *nor) ++{ ++ int ret; ++ u8 val; ++ ++ ret = nor->read_reg(nor, SPINOR_OP_RD_EVCR, &val, 1); ++ if (ret < 0) { ++ dev_err(nor->dev, "error %d reading EVCR\n", ret); ++ return ret; ++ } ++ ++ write_enable(nor); ++ ++ /* set EVCR, enable quad I/O */ ++ nor->cmd_buf[0] = val & ~EVCR_QUAD_EN_MICRON; ++ ret = nor->write_reg(nor, SPINOR_OP_WD_EVCR, nor->cmd_buf, 1); ++ if (ret < 0) { ++ dev_err(nor->dev, "error while writing EVCR register\n"); ++ return ret; ++ } ++ ++ ret = spi_nor_wait_till_ready(nor); ++ if (ret) ++ return ret; ++ ++ /* read EVCR and check it */ ++ ret = nor->read_reg(nor, SPINOR_OP_RD_EVCR, &val, 1); ++ if (ret < 0) { ++ dev_err(nor->dev, "error %d reading EVCR\n", ret); ++ return ret; ++ } ++ if (val & EVCR_QUAD_EN_MICRON) { ++ dev_err(nor->dev, "Micron EVCR Quad bit not clear\n"); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int set_quad_mode(struct spi_nor *nor, const struct flash_info *info) ++{ ++ int status; ++ ++ switch (JEDEC_MFR(info)) { ++ case SNOR_MFR_MACRONIX: ++ status = macronix_quad_enable(nor); ++ if (status) { ++ dev_err(nor->dev, "Macronix quad-read not enabled\n"); ++ return -EINVAL; ++ } ++ return status; ++ case SNOR_MFR_MICRON: ++ status = micron_quad_enable(nor); ++ if (status) { ++ dev_err(nor->dev, "Micron quad-read not enabled\n"); ++ return -EINVAL; ++ } ++ return status; ++ default: ++ status = spansion_quad_enable(nor); ++ if (status) { ++ dev_err(nor->dev, "Spansion quad-read not enabled\n"); ++ return -EINVAL; ++ } ++ return status; ++ } ++} ++ ++static int spi_nor_check(struct spi_nor *nor) ++{ ++ if (!nor->dev || !nor->read || !nor->write || ++ !nor->read_reg || !nor->write_reg || !nor->erase) { ++ pr_err("spi-nor: please fill all the necessary fields!\n"); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) ++{ ++ const struct flash_info *info = NULL; ++ struct device *dev = nor->dev; ++ struct mtd_info *mtd = &nor->mtd; ++ struct device_node *np = nor->flash_node; ++ int ret; ++ int i; ++ ++ ret = spi_nor_check(nor); ++ if (ret) ++ return ret; ++ ++ if (name) ++ info = spi_nor_match_id(name); ++ /* Try to auto-detect if chip name wasn't specified or not found */ ++ if (!info) ++ info = spi_nor_read_id(nor); ++ if (IS_ERR_OR_NULL(info)) ++ return -ENOENT; ++ ++ /* ++ * If caller has specified name of flash model that can normally be ++ * detected using JEDEC, let's verify it. ++ */ ++ if (name && info->id_len) { ++ const struct flash_info *jinfo; ++ ++ jinfo = spi_nor_read_id(nor); ++ if (IS_ERR(jinfo)) { ++ return PTR_ERR(jinfo); ++ } else if (jinfo != info) { ++ /* ++ * JEDEC knows better, so overwrite platform ID. We ++ * can't trust partitions any longer, but we'll let ++ * mtd apply them anyway, since some partitions may be ++ * marked read-only, and we don't want to lose that ++ * information, even if it's not 100% accurate. ++ */ ++ dev_warn(dev, "found %s, expected %s\n", ++ jinfo->name, info->name); ++ info = jinfo; ++ } ++ } ++ ++#ifdef CONFIG_M25PXX_STAY_IN_3BYTE_MODE ++ /* keep the flash_info pointer for use with call to set_4byte() */ ++ nor->priv1 = info; ++#endif ++ ++ mutex_init(&nor->lock); ++ ++ /* ++ * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up ++ * with the software protection bits set ++ */ ++ ++ if (JEDEC_MFR(info) == SNOR_MFR_ATMEL || ++ JEDEC_MFR(info) == SNOR_MFR_INTEL || ++ JEDEC_MFR(info) == SNOR_MFR_SST) { ++ write_enable(nor); ++ write_sr(nor, 0); ++ } ++ ++ if (!mtd->name) ++ mtd->name = dev_name(dev); ++ mtd->priv = nor; ++ mtd->type = MTD_NORFLASH; ++ mtd->writesize = 1; ++ mtd->flags = MTD_CAP_NORFLASH; ++ mtd->size = info->sector_size * info->n_sectors; ++ mtd->_erase = spi_nor_erase; ++ mtd->_read = spi_nor_read; ++ ++ /* NOR protection support for STmicro/Micron chips and similar */ ++ if (JEDEC_MFR(info) == SNOR_MFR_MICRON) { ++ nor->flash_lock = stm_lock; ++ nor->flash_unlock = stm_unlock; ++ nor->flash_is_locked = stm_is_locked; ++ } ++ ++ if (nor->flash_lock && nor->flash_unlock && nor->flash_is_locked) { ++ mtd->_lock = spi_nor_lock; ++ mtd->_unlock = spi_nor_unlock; ++ mtd->_is_locked = spi_nor_is_locked; ++ } ++ ++ /* sst nor chips use AAI word program */ ++ if (info->flags & SST_WRITE) ++ mtd->_write = sst_write; ++ else ++ mtd->_write = spi_nor_write; ++ ++ if (info->flags & USE_FSR) ++ nor->flags |= SNOR_F_USE_FSR; ++ ++#ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS ++ /* prefer "small sector" erase if possible */ ++ if (info->flags & SECT_4K) { ++ nor->erase_opcode = SPINOR_OP_BE_4K; ++ mtd->erasesize = 4096; ++ } else if (info->flags & SECT_4K_PMC) { ++ nor->erase_opcode = SPINOR_OP_BE_4K_PMC; ++ mtd->erasesize = 4096; ++ } else ++#endif ++ { ++ nor->erase_opcode = SPINOR_OP_SE; ++ mtd->erasesize = info->sector_size; ++ } ++ ++ if (info->flags & SPI_NOR_NO_ERASE) ++ mtd->flags |= MTD_NO_ERASE; ++ ++ mtd->dev.parent = dev; ++ nor->page_size = info->page_size; ++ mtd->writebufsize = nor->page_size; ++ ++ if (np) { ++ /* If we were instantiated by DT, use it */ ++ if (of_property_read_bool(np, "m25p,fast-read")) ++ nor->flash_read = SPI_NOR_FAST; ++ else ++ nor->flash_read = SPI_NOR_NORMAL; ++ } else { ++ /* If we weren't instantiated by DT, default to fast-read */ ++ nor->flash_read = SPI_NOR_FAST; ++ } ++ ++ /* Some devices cannot do fast-read, no matter what DT tells us */ ++ if (info->flags & SPI_NOR_NO_FR) ++ nor->flash_read = SPI_NOR_NORMAL; ++ ++ /* Quad/Dual-read mode takes precedence over fast/normal */ ++ if (mode == SPI_NOR_QUAD && info->flags & SPI_NOR_QUAD_READ) { ++ ret = set_quad_mode(nor, info); ++ if (ret) { ++ dev_err(dev, "quad mode not supported\n"); ++ return ret; ++ } ++ nor->flash_read = SPI_NOR_QUAD; ++ } else if (mode == SPI_NOR_DUAL && info->flags & SPI_NOR_DUAL_READ) { ++ nor->flash_read = SPI_NOR_DUAL; ++ } ++ ++ /* Default commands */ ++ switch (nor->flash_read) { ++ case SPI_NOR_QUAD: ++ nor->read_opcode = SPINOR_OP_READ_1_1_4; ++ break; ++ case SPI_NOR_DUAL: ++ nor->read_opcode = SPINOR_OP_READ_1_1_2; ++ break; ++ case SPI_NOR_FAST: ++ nor->read_opcode = SPINOR_OP_READ_FAST; ++ break; ++ case SPI_NOR_NORMAL: ++ nor->read_opcode = SPINOR_OP_READ; ++ break; ++ default: ++ dev_err(dev, "No Read opcode defined\n"); ++ return -EINVAL; ++ } ++ ++ nor->program_opcode = SPINOR_OP_PP; ++ ++ if (info->addr_width) ++ nor->addr_width = info->addr_width; ++ else { ++#ifndef CONFIG_M25PXX_STAY_IN_3BYTE_MODE ++ if (mtd->size > 0x1000000) { ++ /* enable 4-byte addressing if the device exceeds 16MiB */ ++ nor->addr_width = 4; ++ if (JEDEC_MFR(info) == CFI_MFR_AMD) { ++ /* Dedicated 4-byte command set */ ++ switch (nor->flash_read) { ++ case SPI_NOR_QUAD: ++ nor->read_opcode = SPINOR_OP_READ4_1_1_4; ++ break; ++ case SPI_NOR_DUAL: ++ nor->read_opcode = SPINOR_OP_READ4_1_1_2; ++ break; ++ case SPI_NOR_FAST: ++ nor->read_opcode = SPINOR_OP_READ4_FAST; ++ break; ++ case SPI_NOR_NORMAL: ++ nor->read_opcode = SPINOR_OP_READ4; ++ break; ++ } ++ nor->program_opcode = SPINOR_OP_PP_4B; ++ /* No small sector erase for 4-byte command set */ ++ nor->erase_opcode = SPINOR_OP_SE_4B; ++ mtd->erasesize = info->sector_size; ++ } else ++ set_4byte(nor, info, 1); ++ } else ++#endif /* !CONFIG_M25PXX_STAY_IN_3BYTE_MODE */ ++ nor->addr_width = 3; ++ } ++ ++ nor->read_dummy = spi_nor_read_dummy_cycles(nor); ++ ++ dev_info(dev, "%s (%lld Kbytes)\n", info->name, ++ (long long)mtd->size >> 10); ++ ++ dev_dbg(dev, ++ "mtd .name = %s, .size = 0x%llx (%lldMiB), " ++ ".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n", ++ mtd->name, (long long)mtd->size, (long long)(mtd->size >> 20), ++ mtd->erasesize, mtd->erasesize / 1024, mtd->numeraseregions); ++ ++ if (mtd->numeraseregions) ++ for (i = 0; i < mtd->numeraseregions; i++) ++ dev_dbg(dev, ++ "mtd.eraseregions[%d] = { .offset = 0x%llx, " ++ ".erasesize = 0x%.8x (%uKiB), " ++ ".numblocks = %d }\n", ++ i, (long long)mtd->eraseregions[i].offset, ++ mtd->eraseregions[i].erasesize, ++ mtd->eraseregions[i].erasesize / 1024, ++ mtd->eraseregions[i].numblocks); ++ return 0; ++} ++EXPORT_SYMBOL_GPL(spi_nor_scan); ++ ++static const struct flash_info *spi_nor_match_id(const char *name) ++{ ++ const struct flash_info *id = spi_nor_ids; ++ ++ while (id->name) { ++ if (!strcmp(name, id->name)) ++ return id; ++ id++; ++ } ++ return NULL; ++} ++ ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("framework for SPI NOR"); +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig +--- a/drivers/net/ethernet/broadcom/Kconfig 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/Kconfig 2017-11-09 17:53:43.698295000 +0800 +@@ -190,4 +190,8 @@ config BNXT_SRIOV + Virtualization support in the NetXtreme-C/E products. This + allows for virtual function acceleration in virtual environments. + ++source "drivers/net/ethernet/broadcom/gmac/et/Kconfig" ++source "drivers/net/ethernet/broadcom/gmac/hnd/Kconfig" ++source "drivers/net/ethernet/broadcom/mdio/Kconfig" ++ + endif # NET_VENDOR_BROADCOM +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/Makefile b/drivers/net/ethernet/broadcom/Makefile +--- a/drivers/net/ethernet/broadcom/Makefile 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/Makefile 2017-11-09 17:53:43.699295000 +0800 +@@ -11,5 +11,8 @@ obj-$(CONFIG_BNX2X) += bnx2x/ + obj-$(CONFIG_SB1250_MAC) += sb1250-mac.o + obj-$(CONFIG_TIGON3) += tg3.o + obj-$(CONFIG_BGMAC) += bgmac.o ++obj-$(CONFIG_MDIO_XGS_IPROC) += mdio/ ++obj-$(CONFIG_GMAC_XGS_IPROC) += gmac/et/ ++obj-$(CONFIG_GMAC_XGS_IPROC) += gmac/hnd/ + obj-$(CONFIG_SYSTEMPORT) += bcmsysport.o + obj-$(CONFIG_BNXT) += bnxt/ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/et/Kconfig b/drivers/net/ethernet/broadcom/gmac/et/Kconfig +--- a/drivers/net/ethernet/broadcom/gmac/et/Kconfig 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/et/Kconfig 2017-11-09 17:53:43.878296000 +0800 +@@ -0,0 +1,26 @@ ++# ++# Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++# ++# Permission to use, copy, modify, and/or distribute this software for any ++# purpose with or without fee is hereby granted, provided that the above ++# copyright notice and this permission notice appear in all copies. ++# ++# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++# ++config GMAC_XGS_IPROC ++ tristate "BRCM XGS iProc GMAC support " ++ select HND ++ select ET ++ select ET_ALL_PASSIVE_ON ++ depends on ARCH_XGS_IPROC ++ default n ++ help ++ Add GMAC support ++ ++ If unsure, say N. +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/et/Makefile b/drivers/net/ethernet/broadcom/gmac/et/Makefile +--- a/drivers/net/ethernet/broadcom/gmac/et/Makefile 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/et/Makefile 2017-11-09 17:53:43.879292000 +0800 +@@ -0,0 +1,67 @@ ++# ++# Makefile for the Broadcom et driver ++# ++# Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++# ++# Permission to use, copy, modify, and/or distribute this software for any ++# purpose with or without fee is hereby granted, provided that the above ++# copyright notice and this permission notice appear in all copies. ++# ++# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++# ++ETSRCDIR := ../src/et ++ ++et-objs := $(ETSRCDIR)/sys/et_linux.o $(ETSRCDIR)/sys/etc.o ++ ++## from linux dir ########## ++export SRCBASE_et := $(src)/$(ETSRCDIR)/sys/../../ ++KBUILD_CFLAGS += -I$(SRCBASE_et)/include -DBCMDRIVER -Dlinux ++KBUILD_AFLAGS += -I$(SRCBASE_et)/include ++################################# ++obj-$(CONFIG_ET) := et.o ++ ++et-objs += $(ETSRCDIR)/sys/etcgmac.o ++EXTRA_CFLAGS += -DDMA -Wno-error ++EXTRA_CFLAGS += -DGMAC_RATE_LIMITING -DBCMDMA32 -DBCMDBG_ERR ++ ++ifeq ($(CONFIG_BCM_IPROC_GMAC_SG),y) ++EXTRA_CFLAGS += -DBCMDMASGLISTOSL ++endif ++ ++ifeq ($(CONFIG_ET_ALL_PASSIVE_ON),y) ++EXTRA_CFLAGS += -DGMAC_ALL_PASSIVE ++else ++ifeq ($(CONFIG_ET_ALL_PASSIVE_RUNTIME),y) ++EXTRA_CFLAGS += -DGMAC_ALL_PASSIVE ++endif ++endif ++ ++ifeq ($(CONFIG_ET_NAPI_POLL),y) ++EXTRA_CFLAGS += -DGMAC_NAPI_POLL ++else ++ifeq ($(CONFIG_ET_NAPI2_POLL),y) ++EXTRA_CFLAGS += -DGMAC_NAPI2_POLL ++endif ++endif ++ ++EXTRA_CFLAGS += -I$(src)/$(ETSRCDIR)/sys ++ ++ifneq ($(KERNELRELEASE),) ++# kbuild part of makefile ++else ++# Normal makefile ++KERNELDIR := ../../kernel/linux ++all: ++ $(MAKE) -C $(KERNELDIR) M=`pwd` ++ ++clean: ++ $(MAKE) -C $(KERNELDIR) M=`pwd` clean ++endif ++ ++clean-files += $(ETSRCDIR)/sys/*.o $(ETSRCDIR)/sys/.*.o.cmd +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/hnd/Kconfig b/drivers/net/ethernet/broadcom/gmac/hnd/Kconfig +--- a/drivers/net/ethernet/broadcom/gmac/hnd/Kconfig 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/hnd/Kconfig 2017-11-09 17:53:43.880305000 +0800 +@@ -0,0 +1,100 @@ ++# ++# Broadcom Home Networking Division (HND) driver configuration ++# ++# Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++# ++# Permission to use, copy, modify, and/or distribute this software for any ++# purpose with or without fee is hereby granted, provided that the above ++# copyright notice and this permission notice appear in all copies. ++# ++# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++# ++ ++menu "Broadcom HND network devices" ++# Kenlo depends on PCI ++config HND ++ bool "Broadcom HND network device support" ++ depends on GMAC_XGS_IPROC ++config ET ++ tristate "10/100 Ethernet support" ++ depends on HND ++choice ++ prompt "ET ALL PASSIVE mode" ++ depends on ET ++ optional ++config ET_ALL_PASSIVE_ON ++ bool "ET ALL PASSIVE on" ++config ET_ALL_PASSIVE_RUNTIME ++ bool "ET ALL PASSIVE with runtime setting" ++endchoice ++config ET_NAPI2_POLL ++ bool "BCM GMAC NAPI2_POLL" ++ default n ++ depends on !ET_ALL_PASSIVE_ON && !ET_ALL_PASSIVE_RUNTIME ++config BCM_IPROC_GMAC_ACP ++ tristate "BCM GMAC_ACP support" ++ depends on HND ++ default n ++ help ++ Add GMAC_ACP support to improve performance without ++ cache flushing/invalidate. The uboot's bootargs must ++ include "mem=240M" to limit whole Kernel memory inside ++ ACP region which is 256MB from 0x80000000; since kernel ++ starts from 0x81000000, total mem is 240MB only ++ If unsure, say N. ++config BCM_IPROC_GMAC_PREFETCH ++ tristate "BCM GMAC prefetching support" ++ depends on HND ++ default n ++ help ++ If unsure, say N. ++config BCM_IPROC_GMAC_TXONCPU1 ++ tristate "BCM GMAC TX-ON-CPU1 support" ++ depends on HND && SMP && (ET_ALL_PASSIVE_ON || ET_ALL_PASSIVE_RUNTIME) ++ default n ++ help ++ Run "Passive Mode" Tx workthread on CPU1 for ++ multi-cores utilizing; ++ If unsure, say N. ++config BCM_IPROC_GMAC_LOCK_OPT ++ tristate "BCM GMAC LOCK OPTIMIZATION support" ++ depends on HND ++ default n ++ help ++ Minimize locks during Tx/Rx tasks; ++ it is tested under "Passive Mode" (workthread) only. ++ If unsure, say N. ++config BCM_IPROC_GMAC_RWREG_OPT ++ tristate "BCM GMAC R/W_REG OPTIMIZATION support" ++ depends on HND ++ default n ++ help ++ Remove unnecessary "DSB" intructions of R/W_REG Macro. ++ If unsure, say N. ++config BCM_IPROC_GMAC_SG ++ bool "BCM GMAC Scatter Gather support" ++ default n ++ depends on HND ++config IPROC_SDK_MGT_PORT_HANDOFF ++ bool "GMAC SDK Management port handoff" ++ default y ++ depends on HND ++config IPROC_2STAGE_RX ++ bool "GMAC 2 stage packet RX" ++ default n ++ depends on HND ++config SERDES_ASYMMETRIC_MODE ++ bool "GMAC SDK Serdes Asymmetric Mode" ++ default n ++ depends on HND && (MACH_KT2 || MACH_HX4) ++config JUMBO_FRAME ++ bool "GMAC Jumbo Frame Support" ++ default n ++ depends on HND ++endmenu +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/hnd/Makefile b/drivers/net/ethernet/broadcom/gmac/hnd/Makefile +--- a/drivers/net/ethernet/broadcom/gmac/hnd/Makefile 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/hnd/Makefile 2017-11-09 17:53:43.881317000 +0800 +@@ -0,0 +1,121 @@ ++# ++# Makefile for Broadcom Home Networking Division (HND) shared driver code ++# ++# $Copyright Open Broadcom Corporation$ ++# ++# $Id: Makefile,v 1.5 2008-05-02 22:49:54 pmoutarl Exp $ ++# ++ ++SHARED := ../src/shared ++ ++## from linux dir ########## ++export SRCBASE_hnd := $(src)/$(SHARED)/../ ++KBUILD_CFLAGS += -I$(SRCBASE_hnd)/include -DBCMDRIVER -Dlinux ++KBUILD_AFLAGS += -I$(SRCBASE_hnd)/include ++################################# ++obj-$(CONFIG_HND) := hnd.o ++ ++EXTRA_CFLAGS += -DBCMDBG_ERR -DBCMDMA32 ++ ++ifeq ($(CONFIG_BCM_IPROC_GMAC_SG),y) ++EXTRA_CFLAGS += -DBCMDMASGLISTOSL ++endif ++ ++HND_OBJS += $(src)/$(SHARED)/nvramstubs.o ++hnd-objs += $(SHARED)/nvramstubs.o ++ ++HND_OBJS += $(src)/$(SHARED)/hnddma.o ++hnd-objs += $(SHARED)/hnddma.o ++ ++HND_OBJS += $(src)/$(SHARED)/bcmutils.o ++hnd-objs += $(SHARED)/bcmutils.o ++ ++HND_OBJS += $(src)/$(SHARED)/linux_osl.o ++hnd-objs += $(SHARED)/linux_osl.o ++ ++HND_OBJS += $(src)/$(SHARED)/siutils.o ++hnd-objs += $(SHARED)/siutils.o ++ ++HND_OBJS += $(src)/$(SHARED)/aiutils.o ++hnd-objs += $(SHARED)/aiutils.o ++ ++ ++ifeq ($(CONFIG_MACH_HX4),y) ++HND_OBJS += $(src)/$(SHARED)/bcmiproc_serdes.o ++hnd-objs += $(SHARED)/bcmiproc_serdes.o ++ ++HND_OBJS += $(src)/$(SHARED)/bcmiproc_phy5461s.o ++hnd-objs += $(SHARED)/bcmiproc_phy5461s.o ++ ++HND_OBJS += $(src)/$(SHARED)/hx4_erom.o ++hnd-objs += $(SHARED)/hx4_erom.o ++endif ++ ++ifeq ($(CONFIG_MACH_SB2),y) ++HND_OBJS += $(src)/$(SHARED)/bcmiproc_serdes.o ++hnd-objs += $(SHARED)/bcmiproc_serdes.o ++ ++HND_OBJS += $(src)/$(SHARED)/bcmiproc_phy5461s.o ++hnd-objs += $(SHARED)/bcmiproc_phy5461s.o ++ ++HND_OBJS += $(src)/$(SHARED)/sb2_erom.o ++hnd-objs += $(SHARED)/sb2_erom.o ++endif ++ ++ifeq ($(CONFIG_MACH_KT2),y) ++HND_OBJS += $(src)/$(SHARED)/bcmiproc_serdes.o ++hnd-objs += $(SHARED)/bcmiproc_serdes.o ++ ++HND_OBJS += $(src)/$(SHARED)/bcmiproc_phy5461s.o ++hnd-objs += $(SHARED)/bcmiproc_phy5461s.o ++ ++HND_OBJS += $(src)/$(SHARED)/kt2_erom.o ++hnd-objs += $(SHARED)/kt2_erom.o ++endif ++ ++ifeq ($(CONFIG_MACH_HR2),y) ++HND_OBJS += $(src)/$(SHARED)/bcmiproc_phy5221.o ++hnd-objs += $(SHARED)/bcmiproc_phy5221.o ++ ++HND_OBJS += $(src)/$(SHARED)/hr2_erom.o ++hnd-objs += $(SHARED)/hr2_erom.o ++endif ++ ++ifeq ($(CONFIG_MACH_GH),y) ++HND_OBJS += $(src)/$(SHARED)/bcmiproc_phy5481.o ++hnd-objs += $(SHARED)/bcmiproc_phy5481.o ++ ++HND_OBJS += $(src)/$(SHARED)/gh_erom.o ++hnd-objs += $(SHARED)/gh_erom.o ++endif ++ ++ifeq ($(CONFIG_MACH_HR3),y) ++ifeq ($(CONFIG_MACH_WH2),y) ++HND_OBJS += $(src)/$(SHARED)/sgmiiplus2_serdes.o ++hnd-objs += $(SHARED)/sgmiiplus2_serdes.o ++ ++HND_OBJS += $(src)/$(SHARED)/bcmiproc_egphy28.o ++hnd-objs += $(SHARED)/bcmiproc_egphy28.o ++else ++HND_OBJS += $(src)/$(SHARED)/bcmiproc_phy5481.o ++hnd-objs += $(SHARED)/bcmiproc_phy5481.o ++endif ++HND_OBJS += $(src)/$(SHARED)/hr3_erom.o ++hnd-objs += $(SHARED)/hr3_erom.o ++endif ++ ++ifeq ($(CONFIG_MACH_GH2),y) ++HND_OBJS += $(src)/$(SHARED)/sgmiiplus2_serdes.o ++hnd-objs += $(SHARED)/sgmiiplus2_serdes.o ++ ++HND_OBJS += $(src)/$(SHARED)/phy542xx.o ++hnd-objs += $(SHARED)/phy542xx.o ++ ++HND_OBJS += $(src)/$(SHARED)/gh2_erom.o ++hnd-objs += $(SHARED)/gh2_erom.o ++endif ++ ++#$(src)/shared_ksyms.c: $(src)/shared_ksyms.sh $(HND_OBJS) ++# sh -e $< $(HND_OBJS) > $@ ++ ++hnd-objs += shared_ksyms.o +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/hnd/shared_ksyms.c b/drivers/net/ethernet/broadcom/gmac/hnd/shared_ksyms.c +--- a/drivers/net/ethernet/broadcom/gmac/hnd/shared_ksyms.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/hnd/shared_ksyms.c 2017-11-09 17:53:43.882312000 +0800 +@@ -0,0 +1,43 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ */ ++#include ++#include ++#include ++#include ++EXPORT_SYMBOL(bcm_atoi); ++EXPORT_SYMBOL(bcm_binit); ++EXPORT_SYMBOL(bcm_bprintf); ++EXPORT_SYMBOL(bcm_ether_atoe); ++EXPORT_SYMBOL(bcm_ether_ntoa); ++EXPORT_SYMBOL(bcm_strtoul); ++EXPORT_SYMBOL(getgpiopin); ++EXPORT_SYMBOL(getintvar); ++EXPORT_SYMBOL(getvar); ++EXPORT_SYMBOL(nvram_env_gmac_name); ++EXPORT_SYMBOL(nvram_get); ++EXPORT_SYMBOL(osl_delay); ++EXPORT_SYMBOL(osl_detach); ++EXPORT_SYMBOL(osl_dma_map); ++EXPORT_SYMBOL(osl_malloc); ++EXPORT_SYMBOL(osl_malloced); ++EXPORT_SYMBOL(osl_mfree); ++EXPORT_SYMBOL(osl_pkt_frmnative); ++EXPORT_SYMBOL(osl_pkt_tonative); ++EXPORT_SYMBOL(osl_pktfree); ++EXPORT_SYMBOL(pktsetprio); ++EXPORT_SYMBOL(si_attach); ++EXPORT_SYMBOL(si_setcore); ++EXPORT_SYMBOL(si_core_cflags); ++EXPORT_SYMBOL(si_core_disable); ++EXPORT_SYMBOL(si_core_reset); ++EXPORT_SYMBOL(si_core_sflags); ++EXPORT_SYMBOL(si_coreid); ++EXPORT_SYMBOL(si_coreidx); ++EXPORT_SYMBOL(si_corerev); ++EXPORT_SYMBOL(si_coreunit); ++EXPORT_SYMBOL(si_detach); ++EXPORT_SYMBOL(si_gpioout); ++EXPORT_SYMBOL(si_gpioouten); ++EXPORT_SYMBOL(si_iscoreup); ++EXPORT_SYMBOL(si_setcoreidx); +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/hnd/shared_ksyms.sh b/drivers/net/ethernet/broadcom/gmac/hnd/shared_ksyms.sh +--- a/drivers/net/ethernet/broadcom/gmac/hnd/shared_ksyms.sh 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/hnd/shared_ksyms.sh 2017-11-09 17:53:43.883313000 +0800 +@@ -0,0 +1,30 @@ ++#!/bin/sh ++# ++# Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++# ++# Permission to use, copy, modify, and/or distribute this software for any ++# purpose with or without fee is hereby granted, provided that the above ++# copyright notice and this permission notice appear in all copies. ++# ++# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++# ++# $Id: shared_ksyms.sh,v 1.2 2008-12-05 20:10:41 $ ++# ++ ++cat < ++#include ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) ++#include ++#endif ++EOF ++ ++for file in $* ; do ++ ${NM} $file | sed -ne 's/[0-9A-Fa-f]* [BDRT] \([^ ]*\)/extern void \1; EXPORT_SYMBOL(\1);/p' ++done +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_cfg.h b/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_cfg.h +--- a/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_cfg.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_cfg.h 2017-11-09 17:53:43.886293000 +0800 +@@ -0,0 +1,12 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ * ++ * BCM ET driver config options ++ * ++ * $Id: et_cfg.h,v 1.1.4.1 2010-08-05 19:17:00 jaredh Exp $ ++ */ ++ ++#if defined(__NetBSD__) || defined(__FreeBSD__) ++#include ++#include ++#endif /* defined(__NetBSD__) || defined(__FreeBSD__) */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_dbg.h b/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_dbg.h +--- a/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_dbg.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_dbg.h 2017-11-09 17:53:43.896296000 +0800 +@@ -0,0 +1,47 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ * ++ * Minimal debug/trace/assert driver definitions for ++ * Broadcom Home Networking Division 10/100 Mbit/s Ethernet ++ * Device Driver. ++ * ++ * $Id: et_dbg.h 286404 2011-09-27 19:29:08Z nisar $ ++ */ ++ ++#ifndef _et_dbg_ ++#define _et_dbg_ ++ ++#ifdef BCMDBG ++struct ether_header; ++extern void etc_prhdr(char *msg, struct ether_header *eh, uint len, int unit); ++extern void etc_prhex(char *msg, uchar *buf, uint nbytes, int unit); ++/* ++ * et_msg_level is a bitvector: ++ * 0 errors ++ * 1 function-level tracing ++ * 2 one-line frame tx/rx summary ++ * 3 complex frame tx/rx in hex ++ */ ++#define ET_ERROR(args) if (!(et_msg_level & 1)) ; else printf args ++#define ET_TRACE(args) if (!(et_msg_level & 2)) ; else printf args ++#define ET_PRHDR(msg, eh, len, unit) if (!(et_msg_level & 4)) ; else etc_prhdr(msg, eh, len, unit) ++#define ET_PRPKT(msg, buf, len, unit) if (!(et_msg_level & 8)) ; else etc_prhex(msg, buf, len, unit) ++#else /* BCMDBG */ ++#define ET_ERROR(args) ++#define ET_TRACE(args) ++#define ET_PRHDR(msg, eh, len, unit) ++#define ET_PRPKT(msg, buf, len, unit) ++#endif /* BCMDBG */ ++ ++extern uint32 et_msg_level; ++ ++#define ET_LOG(fmt, a1, a2) ++ ++/* include port-specific tunables */ ++#if defined(linux) ++#include ++#else ++#error ++#endif ++ ++#endif /* _et_dbg_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_export.h b/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_export.h +--- a/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_export.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_export.h 2017-11-09 17:53:43.897291000 +0800 +@@ -0,0 +1,28 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ * ++ * Required functions exported by the port-specific (os-dependent) driver ++ * to common (os-independent) driver code. ++ * ++ * $Id: et_export.h 322208 2012-03-20 01:53:23Z rnuti $ ++ */ ++ ++#ifndef _et_export_h_ ++#define _et_export_h_ ++ ++/* misc callbacks */ ++extern void et_init(void *et, uint options); ++extern void et_reset(void *et); ++extern void et_link_up(void *et); ++extern void et_link_down(void *et); ++extern bool et_is_link_up(void *et); ++extern int et_up(void *et); ++extern int et_down(void *et, int reset); ++extern void et_dump(void *et, struct bcmstrbuf *b); ++extern void et_intrson(void *et); ++ ++/* for BCM5222 dual-phy shared mdio contortion */ ++extern void *et_phyfind(void *et, uint coreunit); ++extern uint16 et_phyrd(void *et, uint phyaddr, uint reg); ++extern void et_phywr(void *et, uint reg, uint phyaddr, uint16 val); ++#endif /* _et_export_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_linux.c b/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_linux.c +--- a/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_linux.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_linux.c 2017-11-09 17:53:43.899291000 +0800 +@@ -0,0 +1,2603 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ * ++ * Linux device driver for ++ * Broadcom BCM47XX 10/100/1000 Mbps Ethernet Controller ++ * ++ * $Id: et_linux.c 327582 2012-04-14 05:02:37Z kenlo $ ++ */ ++ ++#include ++#define __UNDEF_NO_VERSION__ ++ ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef SIOCETHTOOL ++#include ++#endif /* SIOCETHTOOL */ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef CONFIG_OF ++#include ++#include ++#include ++#include ++#include ++#endif ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* to be cleaned and fixed */ ++/* to be cleaned Makefile */ ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef CONFIG_BCM_IPROC_GMAC_PREFETCH ++#include ++ ++#define SKB_PREFETCH_LEN (128) ++/* 30 rxhdr + 34 mac & ip */ ++#define SKB_DATA_PREFETCH_LEN (96) ++#endif /* CONFIG_BCM_IPROC_GMAC_PREFETCH */ ++ ++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 4, 5) ++#error Linux version must be newer than 2.4.5 ++#endif /* LINUX_VERSION_CODE <= KERNEL_VERSION(2, 4, 5) */ ++ ++#define MIN_PACKET_SIZE 70 /* for gmac2 (&GMAC3?) */ ++/* if packet is less than 64 bytes, it will not tx */ ++/* if packet is less than 66 bytes, CRC is not generated) */ ++/* this length is after brm tag is stripped off */ ++ ++#define DATAHIWAT 1000 /* data msg txq hiwat mark */ ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36) ++#define HAVE_NET_DEVICE_OPS 1 ++#define HAVE_NETDEV_PRIV 1 ++#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36) */ ++ ++#ifndef HAVE_NETDEV_PRIV ++#define HAVE_NETDEV_PRIV ++#define netdev_priv(dev) ((dev)->priv) ++#define ET_INFO(dev) (et_info_t *)((dev)->priv) ++#else ++#define ET_INFO(dev) netdev_priv(dev) ++#endif /* HAVE_NETDEV_PRIV */ ++ ++#ifdef GMAC_ALL_PASSIVE ++#define ET_LIMIT_TXQ ++#define ET_ALL_PASSIVE_ENAB(et) (!(et)->all_dispatch_mode) ++ ++/* passive mode: 1: enable, 0: disable */ ++static int passivemode = 0; ++module_param(passivemode, int, 0); ++#else /* GMAC_ALL_PASSIVE */ ++#define ET_ALL_PASSIVE_ENAB(et) 0 ++#endif /* GMAC_ALL_PASSIVE */ ++ ++#ifdef ET_LIMIT_TXQ ++#define ET_TXQ_THRESH 0 ++static int et_txq_thresh = ET_TXQ_THRESH; ++module_param(et_txq_thresh, int, 0); ++#endif /* ET_LIMIT_TXQ */ ++ ++ ++/* In 2.6.20 kernels work functions get passed a pointer to the ++ * struct work, so things will continue to work as long as the work ++ * structure is the first component of the task structure. ++ */ ++typedef struct et_task { ++ struct work_struct work; ++ void *context; ++} et_task_t; ++ ++typedef struct et_info { ++ etc_info_t *etc; /* pointer to common os-independent data */ ++ struct net_device *dev; /* backpoint to device */ ++ struct pci_dev *pdev; /* backpoint to pci_dev */ ++ void *osh; /* pointer to os handle */ ++ struct semaphore sem; /* use semaphore to allow sleep */ ++ spinlock_t lock; /* per-device perimeter lock */ ++ spinlock_t txq_lock; /* lock for txq protection */ ++ spinlock_t tx_lock; /* lock for tx protection */ ++ spinlock_t isr_lock; /* lock for irq reentrancy protection */ ++ struct sk_buff_head txq[NUMTXQ];/* send queue */ ++ void *regsva; /* opaque chip registers virtual address */ ++ struct timer_list timer; /* one second watchdog timer */ ++ bool set; /* indicate the timer is set or not */ ++ struct net_device_stats stats; /* stat counter reporting structure */ ++ int events; /* bit channel between isr and dpc */ ++ struct et_info *next; /* pointer to next et_info_t in chain */ ++#ifdef GMAC_NAPI2_POLL ++ struct napi_struct napi_poll; ++#endif /* GMAC_NAPI2_POLL */ ++#ifndef GMAC_NAPI_POLL ++ struct tasklet_struct tasklet;/* dpc tasklet */ ++#endif /* GMAC_NAPI_POLL */ ++#ifdef GMAC_ALL_PASSIVE ++ et_task_t dpc_task; /* work queue for rx dpc */ ++ et_task_t txq_task; /* work queue for tx frames */ ++ bool all_dispatch_mode; /* dispatch mode: tasklets or passive */ ++#endif /* GMAC_ALL_PASSIVE */ ++ bool resched; /* dpc was rescheduled */ ++#ifdef CONFIG_IPROC_2STAGE_RX ++ bool rxinisr; ++#endif /* CONFIG_IPROC_2STAGE_RX */ ++} et_info_t; ++ ++#define ET_LOCK(et) \ ++do { \ ++ if (ET_ALL_PASSIVE_ENAB(et)) \ ++ down(&(et)->sem); \ ++ else \ ++ spin_lock_bh(&(et)->lock); \ ++} while (0) ++ ++#define ET_UNLOCK(et) \ ++do { \ ++ if (ET_ALL_PASSIVE_ENAB(et)) \ ++ up(&(et)->sem); \ ++ else \ ++ spin_unlock_bh(&(et)->lock); \ ++} while (0) ++ ++#define ET_TXQ_LOCK(et) spin_lock_bh(&(et)->txq_lock) ++#define ET_TXQ_UNLOCK(et) spin_unlock_bh(&(et)->txq_lock) ++#define ET_TX_LOCK(et) spin_lock_bh(&(et)->tx_lock) ++#define ET_TX_UNLOCK(et) spin_unlock_bh(&(et)->tx_lock) ++#define INT_LOCK(et, flags) spin_lock_irqsave(&(et)->isr_lock, flags) ++#define INT_UNLOCK(et, flags) spin_unlock_irqrestore(&(et)->isr_lock, flags) ++ ++#ifdef GMAC_RATE_LIMITING ++static int et_rx_rate_limit = 0; ++extern void etc_check_rate_limiting(etc_info_t *etc, void *pch); ++#endif /* GMAC_RATE_LIMITING */ ++ ++#if defined(CONFIG_IPROC_SDK_MGT_PORT_HANDOFF) ++#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) ++extern int gmac_has_mdio_access(void); ++#endif /* (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) */ ++#endif /* defined(CONFIG_IPROC_SDK_MGT_PORT_HANDOFF) */ ++ ++static int et_found = 0; ++static et_info_t *et_list = NULL; ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 37) ++#define init_MUTEX(x) sema_init(x,1) ++#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 37) */ ++ ++/* linux 2.4 doesn't have in_atomic */ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) ++#define in_atomic() 0 ++#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 37) */ ++ ++/* Prototypes called by etc.c */ ++#ifdef CONFIG_BCM_GRO_ENABLE ++void et_flush(void *dev_id); ++#endif /* CONFIG_BCM_GRO_ENABLE */ ++void et_init(et_info_t *et, uint options); ++void et_reset(et_info_t *et); ++void et_up(et_info_t *et); ++void et_down(et_info_t *et, int reset); ++void et_intrson(et_info_t *et); ++void et_dump(et_info_t *et, struct bcmstrbuf *b); ++void et_link_up(et_info_t *et); ++void et_link_down(et_info_t *et); ++bool et_is_link_up(et_info_t *et); ++ ++/* Local prototypes */ ++static void et_free(et_info_t *et); ++static int et_open(struct net_device *dev); ++static int et_close(struct net_device *dev); ++static int et_start(struct sk_buff *skb, struct net_device *dev); ++static int et_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); ++static struct net_device_stats *et_get_stats(struct net_device *dev); ++static int et_set_mac_address(struct net_device *dev, void *addr); ++static void et_set_multicast_list(struct net_device *dev); ++ ++static void et_sendnext(et_info_t *et); ++static void _et_watchdog(struct net_device *data); ++static void et_watchdog(ulong data); ++#ifdef GMAC_ALL_PASSIVE ++static void et_watchdog_task(et_task_t *task); ++static void et_dpc_work(struct et_task *task); ++static int et_schedule_task(et_info_t *et, void (*fn)(struct et_task *task), void *context); ++static void et_txq_work(struct et_task *task); ++#endif /* GMAC_ALL_PASSIVE */ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) ++static irqreturn_t et_isr(int irq, void *dev_id); ++#else ++static irqreturn_t et_isr(int irq, void *dev_id, struct pt_regs *ptregs); ++#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) */ ++static int et_rxevent(osl_t *osh, et_info_t *et, struct chops *chops, void *ch, int quota); ++#ifdef GMAC_NAPI2_POLL ++static int et_poll(struct napi_struct *napi, int budget); ++#elif defined(GMAC_NAPI_POLL) ++static int et_poll(struct net_device *dev, int *budget); ++#else /* ! GMAC_NAPI_POLL */ ++static void et_dpc(ulong data); ++#endif /* GMAC_NAPI_POLL */ ++static void et_error(et_info_t *et, struct sk_buff *skb, void *rxh); ++static void et_sendup(et_info_t *et, struct sk_buff *skb); ++static void et_dumpet(et_info_t *et, struct bcmstrbuf *b); ++static int et_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd); ++static int et_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd); ++static void et_get_driver_info(struct net_device *dev, struct ethtool_drvinfo *info); ++ ++static int eth_mac_proc_create(struct net_device *dev); ++#ifndef CONFIG_OF ++static void eth_mac_proc_remove(void); ++#else ++static void eth_mac_proc_remove(struct net_device *dev); ++#endif ++static int iproc_gmac_drv_probe(struct platform_device*); ++static int __exit iproc_gmac_drv_remove(struct platform_device*); ++#ifdef CONFIG_PM ++static int iproc_gmac_drv_suspend(struct platform_device *pdev, pm_message_t state); ++static int iproc_gmac_drv_resume(struct platform_device *pdev); ++#else /* CONFIG_PM */ ++#define iproc_gmac_drv_suspend NULL ++#define iproc_gmac_drv_resume NULL ++#endif /* CONFIG_PM */ ++ ++#define DISABLE_FA_BYPASS 0 ++#define ENABLE_FA_BYPASS 1 ++ ++#if 0 ++static unsigned int gBypass = DISABLE_FA_BYPASS; ++#endif ++ ++#ifdef BCMDBG ++static uint32 msglevel = 0xdeadbeef; ++module_param(msglevel, uint, 0644); ++#endif /* BCMDBG */ ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) ++static const struct ethtool_ops et_ethtool_ops = { ++ .get_settings = et_get_settings, ++ .set_settings = et_set_settings, ++ .get_drvinfo = et_get_driver_info, ++}; ++#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) */ ++ ++#ifdef HAVE_NET_DEVICE_OPS ++static const struct net_device_ops et_netdev_ops = { ++ .ndo_open = et_open, ++ .ndo_stop = et_close, ++ .ndo_start_xmit = et_start, ++ .ndo_get_stats = et_get_stats, ++ .ndo_set_mac_address = et_set_mac_address, ++ .ndo_set_rx_mode = et_set_multicast_list, ++ .ndo_do_ioctl = et_ioctl, ++}; ++#endif /*HAVE_NET_DEVICE_OPS*/ ++ ++#ifndef CONFIG_OF ++static struct platform_driver gmac_pdrv[IPROC_MAX_GMAC_CORES] = { ++ { ++ .probe = iproc_gmac_drv_probe, ++ .remove = __exit_p(iproc_gmac_drv_remove), ++ .suspend = iproc_gmac_drv_suspend, ++ .resume = iproc_gmac_drv_resume, ++ .driver = { ++ .name = "bcm-gmac0", ++ }, ++ }, ++ { ++ .probe = iproc_gmac_drv_probe, ++ .remove = __exit_p(iproc_gmac_drv_remove), ++ .suspend = iproc_gmac_drv_suspend, ++ .resume = iproc_gmac_drv_resume, ++ .driver = { ++ .name = "bcm-gmac1", ++ }, ++ }, ++ { ++ .probe = iproc_gmac_drv_probe, ++ .remove = __exit_p(iproc_gmac_drv_remove), ++ .suspend = iproc_gmac_drv_suspend, ++ .resume = iproc_gmac_drv_resume, ++ .driver = { ++ .name = "bcm-gmac2", ++ }, ++ }, ++ { ++ .probe = iproc_gmac_drv_probe, ++ .remove = __exit_p(iproc_gmac_drv_remove), ++ .suspend = iproc_gmac_drv_suspend, ++ .resume = iproc_gmac_drv_resume, ++ .driver = { ++ .name = "bcm-gmac3", ++ }, ++ } ++}; ++#endif ++ ++/*int gmac_pdev_loaded[IPROC_NUM_GMACS];*/ ++ ++/***************************************************************************** ++*****************************************************************************/ ++static bool __maybe_unused ++et_ctf_pipeline_loopback(et_info_t *et) ++{ ++ if (et->etc->unit == 3) { ++ return true; ++ } else { ++ return false; ++ } ++} ++ ++#ifdef BCMDMASGLISTOSL ++static int ++et_bcmtag_len(et_info_t *et) ++{ ++ return (et_ctf_pipeline_loopback(et)) ? 8 : 0; ++} ++#endif /* BCMDMASGLISTOSL */ ++ ++static void ++et_free(et_info_t *et) ++{ ++ et_info_t **prev; ++ osl_t *osh; ++ ++ ET_TRACE(("et: et_free\n")); ++ ++ if (et == NULL) { ++ return; ++ } ++ ++ if (et->dev && et->dev->irq) { ++ free_irq(et->dev->irq, et); ++ } ++ ++#ifdef GMAC_NAPI2_POLL ++ napi_disable(&et->napi_poll); ++ netif_napi_del(&et->napi_poll); ++#endif /* GMAC_NAPI2_POLL */ ++ ++ if (et->dev) { ++ unregister_netdev(et->dev); ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) ++ free_netdev(et->dev); ++#else ++ MFREE(et->osh, et->dev, sizeof(struct net_device)); ++#endif ++ et->dev = NULL; ++ } ++ ++ /* free common resources */ ++ if (et->etc) { ++ etc_detach(et->etc); ++ et->etc = NULL; ++ } ++ ++ /* unregister_netdev() calls get_stats() which may read chip registers ++ * so we cannot unmap the chip registers until after calling unregister_netdev() . ++ */ ++ if (et->regsva) { ++ iounmap((void *)et->regsva); ++ et->regsva = NULL; ++ } ++ ++ /* remove us from the global linked list */ ++ for (prev = &et_list; *prev; prev = &(*prev)->next) { ++ if (*prev == et) { ++ *prev = et->next; ++ break; ++ } ++ } ++ ++ osh = et->osh; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) ++ free_netdev(et->dev); ++ et->dev = NULL; ++#else ++ MFREE(et->osh, et, sizeof(et_info_t)); ++#endif ++ ++ if (MALLOCED(osh)) { ++ ET_ERROR(("Memory leak of bytes %d\n", MALLOCED(osh))); ++ } ++ ASSERT(MALLOCED(osh) == 0); ++ ++ osl_detach(osh); ++} ++ ++static int ++et_open(struct net_device *dev) ++{ ++ et_info_t *et = ET_INFO(dev); ++ ++ ET_TRACE(("et%d: et_open\n", et->etc->unit)); ++ ++ et->etc->promisc = (dev->flags & IFF_PROMISC)? TRUE: FALSE; ++ et->etc->allmulti = (dev->flags & IFF_ALLMULTI)? TRUE: et->etc->promisc; ++#ifdef GMAC_RATE_LIMITING ++ et->etc->rl_enabled = et_rx_rate_limit; ++#endif /* GMAC_RATE_LIMITING */ ++ ++ ET_LOCK(et); ++ et_up(et); ++ ET_UNLOCK(et); ++ ++ OLD_MOD_INC_USE_COUNT; ++ ++ return (0); ++} ++ ++static int ++et_close(struct net_device *dev) ++{ ++ et_info_t *et = ET_INFO(dev); ++ ++ ET_TRACE(("et%d: et_close\n", et->etc->unit)); ++ ++ et->etc->promisc = FALSE; ++ et->etc->allmulti = FALSE; ++ ++ ET_LOCK(et); ++ et_down(et, 1); ++ ET_UNLOCK(et); ++ ++ OLD_MOD_DEC_USE_COUNT; ++ ++ return (0); ++} ++ ++#if defined(BCMDMASGLISTOSL) ++/* ++ * Driver level checksum offload. This is being done so that we can advertise ++ * checksum offload support to Linux. ++ */ ++static void BCMFASTPATH_HOST ++et_cso(et_info_t *et, struct sk_buff *skb) ++{ ++ struct ethervlan_header *evh; ++ uint8 *th = skb_transport_header(skb); ++ uint16 thoff, eth_type, *check; ++ uint8 prot; ++ ++ ASSERT(!PKTISCTF(et->osh, skb)); ++ ++ evh = (struct ethervlan_header *)PKTDATA(et->osh, skb); ++ eth_type = ((evh->vlan_type == HTON16(ETHER_TYPE_8021Q)) ? ++ evh->ether_type : evh->vlan_type); ++ ++ /* tcp/udp checksum calculation */ ++ thoff = (th - skb->data); ++ if (eth_type == HTON16(ETHER_TYPE_IP)) { ++ struct iphdr *ih = ip_hdr(skb); ++ prot = ih->protocol; ++ ASSERT((prot == IP_PROT_TCP) || (prot == IP_PROT_UDP)); ++ check = (uint16 *)(th + ((prot == IP_PROT_UDP) ? ++ offsetof(struct udphdr, check) : offsetof(struct tcphdr, check))); ++ *check = 0; ++ skb->csum = skb_checksum(skb, thoff, skb->len - thoff, 0); ++ *check = csum_tcpudp_magic(ih->saddr, ih->daddr, ++ skb->len - thoff, prot, skb->csum); ++ } else if (eth_type == HTON16(ETHER_TYPE_IPV6)) { ++ struct ipv6hdr *ih = ipv6_hdr(skb); ++ prot = IPV6_PROT(ih); ++ ASSERT((prot == IP_PROT_TCP) || (prot == IP_PROT_UDP)); ++ check = (uint16 *)(th + ((prot == IP_PROT_UDP) ? ++ offsetof(struct udphdr, check) : offsetof(struct tcphdr, check))); ++ *check = 0; ++ skb->csum = skb_checksum(skb, thoff, skb->len - thoff, 0); ++ *check = csum_ipv6_magic(&ih->saddr, &ih->daddr, ++ skb->len - thoff, prot, skb->csum); ++ } else { ++ return; ++ } ++ ++ if ((*check == 0) && (prot == IP_PROT_UDP)) { ++ *check = CSUM_MANGLED_0; ++ } ++} ++#endif /* defined(BCMDMASGLISTOSL) */ ++ ++/* ++ * Yeah, queueing the packets on a tx queue instead of throwing them ++ * directly into the descriptor ring in the case of dma is kinda lame, ++ * but this results in a unified transmit path for both dma and pio ++ * and localizes/simplifies the netif_*_queue semantics, too. ++ */ ++static int BCMFASTPATH ++et_start(struct sk_buff *skb, struct net_device *dev) ++{ ++ et_info_t *et = ET_INFO(dev); ++ uint32 q = 0; ++#ifdef BCMDMASGLISTOSL ++ bool sw_cksum = true; ++ struct iphdr *iph = NULL; ++#endif /* BCMDMASGLISTOSL */ ++#ifdef ET_LIMIT_TXQ ++ int qlen; ++#endif /* ET_LIMIT_TXQ */ ++ ++#ifdef BCMDMASGLISTOSL ++ if (!PKTSUMNEEDED(skb)) { ++ sw_cksum = false; ++ } ++ ++ /* can only update checksum once. */ ++ /* if checksum is updated later, don't do it here */ ++ iph = (struct iphdr *)skb->network_header; ++ if (((skb->len + et_bcmtag_len(et)) < MIN_PACKET_SIZE) && ++ ((iph->protocol == IPPROTO_TCP) || (iph->protocol == IPPROTO_UDP))) { ++ sw_cksum = false; ++ } ++ ++ if (sw_cksum) { ++ et_cso(et, skb); ++ } ++#endif /* BCMDMASGLISTOSL */ ++ ++ if (skb_is_nonlinear(skb)) { ++ et->etc->txsgpkt++; ++ } ++ ++ if (skb->len > et->etc->txmaxlen) { ++ et->etc->txmaxlen = skb->len; ++ } ++ ++ ET_TRACE(("et%d: et_start: len %d\n", et->etc->unit, skb->len)); ++ ET_LOG("et%d: et_start: len %d", et->etc->unit, skb->len); ++ ++ et->etc->txfrm++; ++#ifdef ET_LIMIT_TXQ ++#ifndef CONFIG_BCM_IPROC_GMAC_LOCK_OPT ++ ET_TXQ_LOCK(et); ++#endif /* CONFIG_BCM_IPROC_GMAC_LOCK_OPT */ ++ qlen = skb_queue_len(&et->txq[q]); ++#ifndef CONFIG_BCM_IPROC_GMAC_LOCK_OPT ++ ET_TXQ_UNLOCK(et); ++#endif /* CONFIG_BCM_IPROC_GMAC_LOCK_OPT */ ++ if (qlen > et->etc->txqlen) { ++ et->etc->txqlen = qlen; ++ } ++ ++ if (et_txq_thresh && (qlen >= et_txq_thresh)) { ++ //PKTCFREE(et->osh, skb, TRUE); ++ //return 0; ++ et->etc->txfrmdropped++; ++ /* schedule work */ ++#ifdef GMAC_ALL_PASSIVE ++ if (ET_ALL_PASSIVE_ENAB(et)) { ++#ifdef CONFIG_BCM_IPROC_GMAC_TXONCPU1 ++ schedule_work_on(1, &et->txq_task.work); ++#else ++ schedule_work(&et->txq_task.work); ++#endif ++ } ++#endif /* GMAC_ALL_PASSIVE */ ++ return NETDEV_TX_BUSY; ++ } ++#endif /* ET_LIMIT_TXQ */ ++ ++ /* put it on the tx queue and call sendnext */ ++ ET_TXQ_LOCK(et); ++ __skb_queue_tail(&et->txq[q], skb); ++ et->etc->txq_state |= (1 << q); ++ ET_TXQ_UNLOCK(et); ++ ++ if (!ET_ALL_PASSIVE_ENAB(et)) { ++ ET_LOCK(et); ++ et_sendnext(et); ++ ET_UNLOCK(et); ++ } ++#ifdef GMAC_ALL_PASSIVE ++ else { ++#ifdef CONFIG_BCM_IPROC_GMAC_TXONCPU1 ++ schedule_work_on(1, &et->txq_task.work); ++#else ++ schedule_work(&et->txq_task.work); ++#endif /* CONFIG_BCM_IPROC_GMAC_TXONCPU1 */ ++ } ++#endif /* GMAC_ALL_PASSIVE */ ++ ++ ET_LOG("et%d: et_start ret\n", et->etc->unit, 0); ++ ++ return (0); ++} ++ ++static void BCMFASTPATH ++et_sendnext(et_info_t *et) ++{ ++ etc_info_t *etc; ++ struct sk_buff *skb; ++ void *p, *n; ++ uint32 priq = TX_Q0; ++#ifdef DMA ++ uint32 txavail; ++#endif ++#ifdef DBG_PRINT_PKT ++ int tagoff, idx; ++#endif /* DBG_PRINT_PKT */ ++ ++ etc = et->etc; ++ ++ ET_TRACE(("et%d: et_sendnext\n", etc->unit)); ++ ET_LOG("et%d: et_sendnext", etc->unit, 0); ++ ++ /* dequeue packets from highest priority queue and send */ ++ while (1) { ++ ET_TXQ_LOCK(et); ++ ++ if (etc->txq_state == 0) ++ break; ++ ++ priq = etc_priq(etc->txq_state); ++ ++ ET_TRACE(("et%d: txq_state %x priq %d txavail %d\n", ++ etc->unit, etc->txq_state, priq, ++ *(uint *)etc->txavail[priq])); ++ ++ if ((skb = skb_peek(&et->txq[priq])) == NULL) { ++ etc->txq_state &= ~(1 << priq); ++ ET_TXQ_UNLOCK(et); ++ continue; ++ } ++ ++#ifdef DMA ++ /* current highest priority dma queue is full */ ++ txavail = *(uint *)(etc->txavail[priq]); ++ if ((PKTISCHAINED(skb) && (txavail < PKTCCNT(skb))) || (txavail == 0)) ++#else /* DMA */ ++ if (etc->pioactive != NULL) ++#endif /* DMA */ ++ { ++ etc->txdmafull++; ++ break; ++ } ++ ++ skb = __skb_dequeue(&et->txq[priq]); ++ ++ ET_TXQ_UNLOCK(et); ++ ET_PRHDR("tx", (struct ether_header *)skb->data, skb->len, etc->unit); ++ ET_PRPKT("txpkt", skb->data, skb->len, etc->unit); ++ ++#ifdef DBG_PRINT_PKT ++ tagoff = 16; ++ printf("et%d: txpkt len(0x%x) tag:0x%02x%02x%02x%02x\n", etc->unit, skb->len, ++ skb->data[tagoff], skb->data[tagoff+1], skb->data[tagoff+2], skb->data[tagoff+3]); ++ ++ printk("et%d: %s len(0x%x) txpkt:", etc->unit, __FUNCTION__, skb->len); ++ for (idx = 0; idx < skb->len; idx++) { ++ if ((idx % 16) == 0) { ++ printk("\n"); ++ } ++ printk("%02x ", skb->data[idx]); ++ } ++ printk("\n"); ++#endif /* DBG_PRINT_PKT */ ++ ++ /* convert the packet. */ ++ p = PKTFRMNATIVE(etc->osh, skb); ++ ASSERT(p != NULL); ++ ++ ET_TRACE(("%s: sdu %p chained %d chain sz %d next %p\n", ++ __FUNCTION__, p, PKTISCHAINED(p), PKTCCNT(p), PKTCLINK(p))); ++ ++ ET_TX_LOCK(et); ++ FOREACH_CHAINED_PKT(p, n) { ++ /* replicate vlan header contents from curr frame */ ++ if (n != NULL) { ++ uint8 *n_evh; ++ n_evh = PKTPUSH(et->osh, n, VLAN_TAG_LEN); ++ *(struct ethervlan_header *)n_evh = ++ *(struct ethervlan_header *)PKTDATA(et->osh, p); ++ } ++ (*etc->chops->tx)(etc->ch, p); ++#ifdef CONFIG_BCM_IPROC_GMAC_LOCK_OPT ++ ET_LOCK(et); ++#endif /* CONFIG_BCM_IPROC_GMAC_LOCK_OPT */ ++ etc->txframe++; ++ etc->txbyte += PKTLEN(et->osh, p); ++#ifdef CONFIG_BCM_IPROC_GMAC_LOCK_OPT ++ ET_UNLOCK(et); ++#endif /* CONFIG_BCM_IPROC_GMAC_LOCK_OPT */ ++ } ++ ET_TX_UNLOCK(et); ++ } ++ ++ /* no flow control when qos is enabled */ ++ if (!et->etc->qos) { ++ /* stop the queue whenever txq fills */ ++ if ((skb_queue_len(&et->txq[TX_Q0]) > DATAHIWAT) && !netif_queue_stopped(et->dev)) { ++ et->etc->txqstop++; ++ netif_stop_queue(et->dev); ++ } else if (netif_queue_stopped(et->dev) && ++ (skb_queue_len(&et->txq[TX_Q0]) < (DATAHIWAT/2))) { ++ netif_wake_queue(et->dev); ++ } ++ } else { ++ /* drop the frame if corresponding prec txq len exceeds hiwat ++ * when qos is enabled. ++ */ ++ if ((priq != TC_NONE) && (skb_queue_len(&et->txq[priq]) > DATAHIWAT)) { ++ skb = __skb_dequeue(&et->txq[priq]); ++ PKTCFREE(et->osh, skb, TRUE); ++ ET_ERROR(("et%d: %s: txqlen %d\n", et->etc->unit, ++ __FUNCTION__, skb_queue_len(&et->txq[priq]))); ++ } ++ } ++ ++ ET_TXQ_UNLOCK(et); ++} ++ ++#ifdef CONFIG_BCM_GRO_ENABLE ++#ifdef CONFIG_ET_MODULE ++extern int et_flushptr_ready; ++extern void (*et_flushptr)(void *dev_id); ++#endif /* CONFIG_ET_MODULE */ ++ ++void ++et_flush(void *dev_id) ++{ ++ et_info_t *et; ++ struct chops *chops; ++ void *ch; ++ osl_t *osh; ++ ++ et = (et_info_t *)dev_id; ++ chops = et->etc->chops; ++ ch = et->etc->ch; ++ osh = et->etc->osh; ++ ++ /* guard against shared interrupts */ ++ if (!et->etc->up) { ++ ET_TRACE(("et%d: et_isr: not up\n", et->etc->unit)); ++ return; ++ } ++ if (!et->napi_poll.gro_list) { ++ return; ++ } ++ ++ /* disable interrupts */ ++ (*chops->intrsoff)(ch); ++ ++ et->resched = TRUE; ++ ++ napi_gro_flush(&et->napi_poll); ++ ++ /* enable interrupts now */ ++ (*chops->intrson)(ch); ++} ++#endif /* CONFIG_BCM_GRO_ENABLE */ ++ ++void ++et_init(et_info_t *et, uint options) ++{ ++ ET_TRACE(("et%d: et_init\n", et->etc->unit)); ++ ET_LOG("et%d: et_init", et->etc->unit, 0); ++ ++ etc_init(et->etc, options); ++ ++#ifdef CONFIG_BCM_GRO_ENABLE ++#ifdef CONFIG_ET_MODULE ++ et_flushptr = &et_flush; ++ et_flushptr_ready = 1; ++#endif /* CONFIG_ET_MODULE */ ++#endif /* CONFIG_BCM_GRO_ENABLE */ ++ ++#if defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_HR2) || defined(CONFIG_MACH_KT2) ++ netif_carrier_off(et->dev); ++#endif /* defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_HR2) || defined(CONFIG_MACH_KT2) */ ++} ++ ++ ++void ++et_reset(et_info_t *et) ++{ ++ ET_TRACE(("et%d: et_reset\n", et->etc->unit)); ++ ++ etc_reset(et->etc); ++ ++ /* zap any pending dpc interrupt bits */ ++ et->events = 0; ++ ++ /* dpc will not be rescheduled */ ++ et->resched = 0; ++} ++ ++void ++et_up(et_info_t *et) ++{ ++ etc_info_t *etc; ++ ++ etc = et->etc; ++ ++ if (etc->up) { ++ return; ++ } ++ ++ ET_TRACE(("et%d: et_up\n", etc->unit)); ++ ++ etc_up(etc); ++ ++#if defined(CONFIG_IPROC_SDK_MGT_PORT_HANDOFF) ++#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) ++ if (et->set) { ++ /* This will happen if running watchdog to monitor mdio bus */ ++ /* and port not up */ ++ del_timer(&et->timer); ++ et->set = FALSE; ++ } ++#endif /* (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) */ ++#endif /* defined(CONFIG_IPROC_SDK_MGT_PORT_HANDOFF) */ ++ ++ /* schedule one second watchdog timer */ ++ et->timer.expires = jiffies + HZ; ++ add_timer(&et->timer); ++ et->set=TRUE; ++ ++ netif_start_queue(et->dev); ++} ++ ++void ++et_down(et_info_t *et, int reset) ++{ ++ etc_info_t *etc; ++ struct sk_buff *skb; ++ int32 i; ++ bool stoptmr = TRUE; ++ ++ etc = et->etc; ++ ++ ET_TRACE(("et%d: et_down\n", etc->unit)); ++ ++ netif_down(et->dev); ++ netif_stop_queue(et->dev); ++ ++#ifdef CONFIG_IPROC_SDK_MGT_PORT_HANDOFF ++#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) ++ if (gmac_has_mdio_access()) { ++ /* we have mdio bus don't stop timer so we can continue to monitor */ ++ stoptmr = FALSE; ++ } ++#endif /* (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) */ ++#endif /* CONFIG_IPROC_SDK_MGT_PORT_HANDOFF */ ++ ++ if ( stoptmr ) { ++ /* stop watchdog timer */ ++ del_timer(&et->timer); ++ et->set = FALSE; ++ } ++ ++#ifdef GMAC_RATE_LIMITING ++ /* stop ratelimiting timer */ ++ del_timer(&et->etc->rl_timer); ++ et->etc->rl_set = FALSE; ++#endif /* GMAC_RATE_LIMITING */ ++ ++ etc_down(etc, reset); ++ ++ /* flush the txq(s) */ ++ for (i = 0; i < NUMTXQ; i++) { ++ while ((skb = skb_dequeue(&et->txq[i]))) { ++ PKTFREE(etc->osh, skb, TRUE); ++ } ++ } ++ ++#if !defined(GMAC_NAPI_POLL) && !defined(GMAC_NAPI2_POLL) ++ /* kill dpc */ ++ ET_UNLOCK(et); ++ tasklet_kill(&et->tasklet); ++ ET_LOCK(et); ++#endif /* GMAC_NAPI_POLL */ ++} ++ ++/* ++ * These are interrupt on/off entry points. Disable interrupts ++ * during interrupt state transition. ++ */ ++void ++et_intrson(et_info_t *et) ++{ ++ unsigned long flags; ++ INT_LOCK(et, flags); ++ (*et->etc->chops->intrson)(et->etc->ch); ++ INT_UNLOCK(et, flags); ++} ++ ++static void ++_et_watchdog(struct net_device *dev) ++{ ++ et_info_t *et; ++ ++ et = ET_INFO(dev); ++ ++ ET_LOCK(et); ++ ++ etc_watchdog(et->etc); ++ ++ if (et->set) { ++ /* reschedule one second watchdog timer */ ++ et->timer.expires = jiffies + HZ; ++ add_timer(&et->timer); ++ } ++#if defined(CONFIG_IPROC_SDK_MGT_PORT_HANDOFF) ++#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) ++ /* this in case port when up then down before we released mdio */ ++ else if (gmac_has_mdio_access()) { ++ /* interface not up but we have mdio bus */ ++ /* reschedule one second watchdog timer */ ++ et->timer.expires = jiffies + HZ; ++ add_timer(&et->timer); ++ et->set = TRUE; ++ } ++#endif /* (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) */ ++#endif /* defined(CONFIG_IPROC_SDK_MGT_PORT_HANDOFF) */ ++ ++ ET_UNLOCK(et); ++} ++ ++#ifdef GMAC_ALL_PASSIVE ++/* Schedule a completion handler to run at safe time */ ++static int ++et_schedule_task(et_info_t *et, void (*fn)(struct et_task *task), void *context) ++{ ++ et_task_t *task; ++ ++ ET_TRACE(("et%d: et_schedule_task\n", et->etc->unit)); ++ ++ if (!(task = MALLOC(et->osh, sizeof(et_task_t)))) { ++ ET_ERROR(("et%d: et_schedule_task: out of memory, malloced %d bytes\n", ++ et->etc->unit, MALLOCED(et->osh))); ++ return -ENOMEM; ++ } ++ ++ MY_INIT_WORK(&task->work, (work_func_t)fn); ++ task->context = context; ++ ++ if (!schedule_work(&task->work)) { ++ ET_ERROR(("et%d: schedule_work() failed\n", et->etc->unit)); ++ MFREE(et->osh, task, sizeof(et_task_t)); ++ return -ENOMEM; ++ } ++ ++ return 0; ++} ++ ++static void BCMFASTPATH ++et_txq_work(struct et_task *task) ++{ ++ et_info_t *et = (et_info_t *)task->context; ++ ++#ifndef CONFIG_BCM_IPROC_GMAC_LOCK_OPT ++ ET_LOCK(et); ++#endif /* !CONFIG_BCM_IPROC_GMAC_LOCK_OPT */ ++ ++ et_sendnext(et); ++ ++#ifndef CONFIG_BCM_IPROC_GMAC_LOCK_OPT ++ ET_UNLOCK(et); ++#endif /* !CONFIG_BCM_IPROC_GMAC_LOCK_OPT */ ++ return; ++} ++ ++static void ++et_watchdog_task(et_task_t *task) ++{ ++ et_info_t *et = ET_INFO((struct net_device *)task->context); ++ ++ _et_watchdog((struct net_device *)task->context); ++ MFREE(et->osh, task, sizeof(et_task_t)); ++} ++#endif /* GMAC_ALL_PASSIVE */ ++ ++static void ++et_watchdog(ulong data) ++{ ++ struct net_device *dev = (struct net_device *)data; ++ ++#ifdef GMAC_ALL_PASSIVE ++ et_info_t *et = ET_INFO(dev); ++#endif /* GMAC_ALL_PASSIVE */ ++ ++ if (!ET_ALL_PASSIVE_ENAB(et)) { ++ _et_watchdog(dev); ++ } ++#ifdef GMAC_ALL_PASSIVE ++ else { ++ et_schedule_task(et, et_watchdog_task, dev); ++ } ++#endif /* GMAC_ALL_PASSIVE */ ++} ++ ++/* Rate limiting */ ++#ifdef GMAC_RATE_LIMITING ++static void et_release_congestion(ulong data) ++{ ++ struct net_device *dev = (struct net_device *)data; ++ et_info_t *et = ET_INFO(dev); ++ ++ if (!et) { ++ return; ++ } ++ ++ if (et->etc->rl_stopping_broadcasts) { ++ et->etc->rl_stopping_broadcasts = 0; ++ /* Clear the number of dropped broadcast packets */ ++ et->etc->rl_dropped_bc_packets = 0; ++ } ++ if (et->etc->rl_stopping_all_packets) { ++ et->etc->rl_stopping_all_packets = 0; ++ et->etc->rl_dropped_all_packets = 0; ++ } ++} ++#endif /* GMAC_RATE_LIMITING */ ++ ++ ++ ++static int ++et_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) ++{ ++ et_info_t *et = ET_INFO(dev); ++ ++ ecmd->supported = (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | ++ SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | ++ SUPPORTED_Autoneg | SUPPORTED_TP); ++#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) ++ ecmd->supported |= SUPPORTED_1000baseT_Full | SUPPORTED_Pause; ++#endif ++#if defined(CONFIG_MACH_HR2) ++ ecmd->supported |= SUPPORTED_Pause; ++#endif ++ ++ ecmd->advertising = ADVERTISED_TP; ++ ecmd->advertising |= (et->etc->advertise & ADV_10HALF) ? ++ ADVERTISED_10baseT_Half : 0; ++ ecmd->advertising |= (et->etc->advertise & ADV_10FULL) ? ++ ADVERTISED_10baseT_Full : 0; ++ ecmd->advertising |= (et->etc->advertise & ADV_100HALF) ? ++ ADVERTISED_100baseT_Half : 0; ++ ecmd->advertising |= (et->etc->advertise & ADV_100FULL) ? ++ ADVERTISED_100baseT_Full : 0; ++ ecmd->advertising |= (et->etc->advertise2 & ADV_1000FULL) ? ++ ADVERTISED_1000baseT_Full : 0; ++ ecmd->advertising |= (et->etc->advertise2 & ADV_1000HALF) ? ++ ADVERTISED_1000baseT_Half : 0; ++ ecmd->advertising |= (et->etc->forcespeed == ET_AUTO) ? ++ ADVERTISED_Autoneg : 0; ++#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || defined(CONFIG_MACH_HR2)) ++ ecmd->advertising |= ADVERTISED_Pause; ++#endif ++ if (et->etc->linkstate) { ++ ecmd->speed = (et->etc->speed == 1000) ? SPEED_1000 : ++ ((et->etc->speed == 100) ? SPEED_100 : SPEED_10); ++ ecmd->duplex = (et->etc->duplex == 1) ? DUPLEX_FULL : DUPLEX_HALF; ++ } else { ++ ecmd->speed = 0; ++ ecmd->duplex = 0; ++ } ++ ecmd->port = PORT_TP; ++ ecmd->phy_address = et->etc->phyaddr; ++ ecmd->transceiver = XCVR_INTERNAL; ++ ecmd->autoneg = (et->etc->forcespeed == ET_AUTO) ? AUTONEG_ENABLE : AUTONEG_DISABLE; ++ ecmd->maxtxpkt = 0; ++ ecmd->maxrxpkt = 0; ++ ++ return 0; ++} ++ ++static int ++et_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) ++{ ++ int speed[2]; ++ ++ et_info_t *et = ET_INFO(dev); ++ ++ if (!capable(CAP_NET_ADMIN)) ++ return (-EPERM); ++ ++ if (ecmd->autoneg == AUTONEG_ENABLE) { ++ speed[0] = ET_AUTO; ++ speed[1] = ecmd->advertising; ++ } else if (ecmd->speed == SPEED_10 && ecmd->duplex == DUPLEX_HALF) { ++ speed[0] = ET_10HALF; ++ } else if (ecmd->speed == SPEED_10 && ecmd->duplex == DUPLEX_FULL) { ++ speed[0] = ET_10FULL; ++ } else if (ecmd->speed == SPEED_100 && ecmd->duplex == DUPLEX_HALF) { ++ speed[0] = ET_100HALF; ++ } else if (ecmd->speed == SPEED_100 && ecmd->duplex == DUPLEX_FULL) { ++ speed[0] = ET_100FULL; ++ } else if (ecmd->speed == SPEED_1000 && ecmd->duplex == DUPLEX_FULL) { ++ speed[0] = ET_1000FULL; ++ } else { ++ return (-EINVAL); ++ } ++ ++ return etc_ioctl(et->etc, ETCSPEED, speed); ++} ++ ++static void ++et_get_driver_info(struct net_device *dev, struct ethtool_drvinfo *info) ++{ ++ et_info_t *et = ET_INFO(dev); ++ bzero(info, sizeof(struct ethtool_drvinfo)); ++ info->cmd = ETHTOOL_GDRVINFO; ++ sprintf(info->driver, "et%d", et->etc->unit); ++ strncpy(info->version, EPI_VERSION_STR, sizeof(info->version)); ++ info->version[(sizeof(info->version))-1] = '\0'; ++} ++ ++#ifdef SIOCETHTOOL ++static int ++et_ethtool(et_info_t *et, struct ethtool_cmd *ecmd) ++{ ++ int ret = 0; ++ ++ ET_LOCK(et); ++ ++ switch (ecmd->cmd) { ++ case ETHTOOL_GSET: ++ ret = et_get_settings(et->dev, ecmd); ++ break; ++ case ETHTOOL_SSET: ++ ret = et_set_settings(et->dev, ecmd); ++ break; ++ case ETHTOOL_GDRVINFO: ++ et_get_driver_info(et->dev, (struct ethtool_drvinfo *)ecmd); ++ break; ++ default: ++ ret = -EINVAL; ++ break; ++ } ++ ++ ET_UNLOCK(et); ++ ++ return (ret); ++} ++#endif /* SIOCETHTOOL */ ++ ++static int ++et_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ++{ ++ et_info_t *et; ++ int error; ++ char *buf; ++ int size, ethtoolcmd; ++ bool get = 0, set; ++ et_var_t *var = NULL; ++ void *buffer = NULL; ++ ++ et = ET_INFO(dev); ++ ++ ET_TRACE(("et%d: et_ioctl: cmd 0x%x\n", et->etc->unit, cmd)); ++ ++ switch (cmd) { ++#ifdef SIOCETHTOOL ++ case SIOCETHTOOL: ++ if (copy_from_user(ðtoolcmd, ifr->ifr_data, sizeof(uint32))) ++ return (-EFAULT); ++ ++ if (ethtoolcmd == ETHTOOL_GDRVINFO) ++ size = sizeof(struct ethtool_drvinfo); ++ else ++ size = sizeof(struct ethtool_cmd); ++ get = TRUE; set = TRUE; ++ break; ++#endif /* SIOCETHTOOL */ ++ case SIOCGETCDUMP: ++ size = IOCBUFSZ; ++ get = TRUE; set = FALSE; ++ break; ++ case SIOCGETCPHYRD: ++ case SIOCGETCPHYRD2: ++ case SIOCGETCROBORD: ++ size = sizeof(int) * 2; ++ get = TRUE; set = TRUE; ++ break; ++ case SIOCSETCSPEED: ++ case SIOCSETCPHYWR: ++ case SIOCSETCPHYWR2: ++ case SIOCSETCROBOWR: ++ size = sizeof(int) * 2; ++ get = FALSE; set = TRUE; ++ break; ++ case SIOCSETGETVAR: ++ size = sizeof(et_var_t); ++ set = TRUE; ++ break; ++ default: ++ size = sizeof(int); ++ get = FALSE; set = TRUE; ++ break; ++ } ++ ++ if ((buf = MALLOC(et->osh, size)) == NULL) { ++ ET_ERROR(("et: et_ioctl: out of memory, malloced %d bytes\n", MALLOCED(et->osh))); ++ return (-ENOMEM); ++ } ++ ++ if (set && copy_from_user(buf, ifr->ifr_data, size)) { ++ MFREE(et->osh, buf, size); ++ return (-EFAULT); ++ } ++ ++ if (cmd == SIOCSETGETVAR) { ++ var = (et_var_t *)buf; ++ if (var->buf) { ++ if (!var->set) ++ get = TRUE; ++ ++ if (!(buffer = (void *) MALLOC(et->osh, var->len))) { ++ ET_ERROR(("et: et_ioctl: out of memory, malloced %d bytes\n", ++ MALLOCED(et->osh))); ++ MFREE(et->osh, buf, size); ++ return (-ENOMEM); ++ } ++ ++ if (copy_from_user(buffer, var->buf, var->len)) { ++ MFREE(et->osh, buffer, var->len); ++ MFREE(et->osh, buf, size); ++ return (-EFAULT); ++ } ++ } ++ } ++ ++ switch (cmd) { ++#ifdef SIOCETHTOOL ++ case SIOCETHTOOL: ++ error = et_ethtool(et, (struct ethtool_cmd *)buf); ++ break; ++#endif /* SIOCETHTOOL */ ++ case SIOCSETGETVAR: ++ ET_LOCK(et); ++ error = etc_iovar(et->etc, var->cmd, var->set, buffer); ++ ET_UNLOCK(et); ++ if (!error && get) { ++ error = copy_to_user(var->buf, buffer, var->len); ++ } ++ ++ if (buffer) { ++ MFREE(et->osh, buffer, var->len); ++ } ++ break; ++ default: ++ ET_LOCK(et); ++ error = etc_ioctl(et->etc, cmd - SIOCSETCUP, buf) ? -EINVAL : 0; ++ ET_UNLOCK(et); ++ break; ++ } ++ ++ if (!error && get) { ++ error = copy_to_user(ifr->ifr_data, buf, size); ++ } ++ ++ MFREE(et->osh, buf, size); ++ ++ return (error); ++} ++ ++static struct net_device_stats * ++et_get_stats(struct net_device *dev) ++{ ++ et_info_t *et; ++ etc_info_t *etc; ++ struct net_device_stats *stats; ++ int locked = 0; ++ ++ et = ET_INFO(dev); ++ ++ ET_TRACE(("et%d: et_get_stats\n", et->etc->unit)); ++ ++ if (!in_atomic()) { ++ locked = 1; ++ ET_LOCK(et); ++ } ++ ++ etc = et->etc; ++ stats = &et->stats; ++ bzero(stats, sizeof(struct net_device_stats)); ++ ++ /* refresh stats */ ++ if (et->etc->up) { ++ (*etc->chops->statsupd)(etc->ch); ++ } ++ ++ /* SWAG */ ++ stats->rx_packets = etc->rxframe; ++ stats->tx_packets = etc->txframe; ++ stats->rx_bytes = etc->rxbyte; ++ stats->tx_bytes = etc->txbyte; ++ stats->rx_errors = etc->rxerror; ++ stats->tx_errors = etc->txerror; ++ ++ if (ET_GMAC(etc)) { ++ gmacmib_t *mib; ++ ++ mib = etc->mib; ++ stats->collisions = mib->tx_total_cols; ++ stats->rx_length_errors = (mib->rx_oversize_pkts + mib->rx_undersize); ++ stats->rx_crc_errors = mib->rx_crc_errs; ++ stats->rx_frame_errors = mib->rx_align_errs; ++ stats->rx_missed_errors = mib->rx_missed_pkts; ++ } else { ++ bcmenetmib_t *mib; ++ ++ mib = etc->mib; ++ stats->collisions = mib->tx_total_cols; ++ stats->rx_length_errors = (mib->rx_oversize_pkts + mib->rx_undersize); ++ stats->rx_crc_errors = mib->rx_crc_errs; ++ stats->rx_frame_errors = mib->rx_align_errs; ++ stats->rx_missed_errors = mib->rx_missed_pkts; ++ ++ } ++ ++ stats->rx_fifo_errors = etc->rxoflo; ++ stats->rx_over_errors = etc->rxoflo; ++ stats->tx_fifo_errors = etc->txuflo; ++ ++ if (locked) { ++ ET_UNLOCK(et); ++ } ++ ++ return (stats); ++} ++ ++static int ++et_set_mac_address(struct net_device *dev, void *addr) ++{ ++ et_info_t *et; ++ struct sockaddr *sa = (struct sockaddr *) addr; ++ ++ et = ET_INFO(dev); ++ ET_TRACE(("et%d: et_set_mac_address\n", et->etc->unit)); ++ ++ if (et->etc->up) { ++ return -EBUSY; ++ } ++ ++ bcopy(sa->sa_data, dev->dev_addr, ETHER_ADDR_LEN); ++ bcopy(dev->dev_addr, &et->etc->cur_etheraddr, ETHER_ADDR_LEN); ++ ++ return 0; ++} ++ ++static void ++et_set_multicast_list(struct net_device *dev) ++{ ++ et_info_t *et; ++ etc_info_t *etc; ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) ++ struct dev_mc_list *mclist; ++#else ++ struct netdev_hw_addr *ha ; ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) */ ++ int i; ++ int locked = 0; ++ ++ et = ET_INFO(dev); ++ etc = et->etc; ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) ++ mclist = NULL ; /* fend off warnings */ ++#else ++ ha = NULL ; ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) */ ++ ++ ET_TRACE(("et%d: et_set_multicast_list\n", etc->unit)); ++ ++ if (!in_atomic()) { ++ locked = 1; ++ ET_LOCK(et); ++ } ++ ++ if (etc->up) { ++ etc->promisc = (dev->flags & IFF_PROMISC)? TRUE: FALSE; ++ etc->allmulti = (dev->flags & IFF_ALLMULTI)? TRUE: etc->promisc; ++ ++ /* copy the list of multicasts into our private table */ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) ++ for (i = 0, mclist = dev->mc_list; mclist && (i < dev->mc_count); ++ i++, mclist = mclist->next) { ++ if (i >= MAXMULTILIST) { ++ etc->allmulti = TRUE; ++ i = 0; ++ break; ++ } ++ etc->multicast[i] = *((struct ether_addr *)mclist->dmi_addr); ++ } ++#else /* >= 2.6.36 */ ++ i = 0; ++ netdev_for_each_mc_addr(ha, dev) { ++ i ++; ++ if (i >= MAXMULTILIST) { ++ etc->allmulti = TRUE; ++ i = 0; ++ break; ++ } ++ etc->multicast[i] = *((struct ether_addr *)ha->addr); ++ } /* for each ha */ ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) */ ++ etc->nmulticast = i; ++ ++ /* LR: partial re-init, DMA is already initialized */ ++ et_init(et, ET_INIT_INTRON); ++ } ++ ++ if (locked) { ++ ET_UNLOCK(et); ++ } ++} ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) ++static irqreturn_t BCMFASTPATH ++et_isr(int irq, void *dev_id) ++#else ++static irqreturn_t BCMFASTPATH ++et_isr(int irq, void *dev_id, struct pt_regs *ptregs) ++#endif ++{ ++ et_info_t *et; ++ struct chops *chops; ++ void *ch; ++ uint events = 0; ++ osl_t *osh; ++ ++ et = (et_info_t *)dev_id; ++ chops = et->etc->chops; ++ ch = et->etc->ch; ++ osh = et->etc->osh; ++ ++ /* guard against shared interrupts */ ++ if (!et->etc->up) { ++ ET_TRACE(("et%d: et_isr: not up\n", et->etc->unit)); ++ goto done; ++ } ++ ++ /* get interrupt condition bits */ ++ events = (*chops->getintrevents)(ch, TRUE); ++ ++ /* not for us */ ++ if (!(events & INTR_NEW)) { ++ goto done; ++ } ++ ++ ET_TRACE(("et%d: et_isr: events 0x%x\n", et->etc->unit, events)); ++ ET_LOG("et%d: et_isr: events 0x%x", et->etc->unit, events); ++ ++#ifdef CONFIG_IPROC_2STAGE_RX ++ if (events & INTR_RX) { ++ et->rxinisr = true; ++ /* process a few RX interrupts */ ++ et_rxevent(osh, et, chops, ch, 1); ++ ++ et->rxinisr = false; ++ /* get interrupt condition bits */ ++ events = (*chops->getintrevents)(ch, TRUE); ++ et->resched = FALSE; ++ ++ /* not for us */ ++ if (!(events & INTR_NEW)) { ++ goto done; ++ } ++ } ++#endif /* CONFIG_IPROC_2STAGE_RX */ ++ ++ /* disable interrupts */ ++ (*chops->intrsoff)(ch); ++ ++ /* save intstatus bits */ ++ ASSERT(et->events == 0); ++ et->events = events; ++ ++ ASSERT(et->resched == FALSE); ++ ++#ifdef GMAC_NAPI2_POLL ++ napi_schedule(&et->napi_poll); ++#elif defined(GMAC_NAPI_POLL) ++ /* allow the device to be added to the cpu polling list if we are up */ ++ if (netif_rx_schedule_prep(et->dev)) { ++ /* tell the network core that we have packets to send up */ ++ __netif_rx_schedule(et->dev); ++ } else { ++ ET_ERROR(("et%d: et_isr: intr while in poll!\n", ++ et->etc->unit)); ++ (*chops->intrson)(ch); ++ } ++#else /* ! GMAC_NAPI_POLL && ! GMAC_NAPI2_POLL */ ++ /* schedule dpc */ ++#ifdef GMAC_ALL_PASSIVE ++ if (ET_ALL_PASSIVE_ENAB(et)) { ++ schedule_work(&et->dpc_task.work); ++ } else ++#endif /* GMAC_ALL_PASSIVE */ ++ { ++ tasklet_schedule(&et->tasklet); ++ } ++#endif /* GMAC_NAPI_POLL */ ++ ++done: ++ ET_LOG("et%d: et_isr ret", et->etc->unit, 0); ++ ++ return IRQ_RETVAL(events & INTR_NEW); ++} ++ ++static inline int ++et_rxevent(osl_t *osh, et_info_t *et, struct chops *chops, void *ch, int quota) ++{ ++ uint processed = 0; ++ void *p, *h = NULL, *t = NULL; ++ struct sk_buff *skb; ++ ++#ifdef GMAC_RATE_LIMITING ++ /* rate limiting */ ++ if (et->etc->rl_enabled) { ++ etc_check_rate_limiting(et->etc, ch); ++ } ++#endif /* GMAC_RATE_LIMITING */ ++ ++ /* read the buffers first */ ++ while ((p = (*chops->rx)(ch))) { ++ PKTSETLINK(p, NULL); ++ if (t == NULL) { ++ h = t = p; ++ } else { ++ PKTSETLINK(t, p); ++ t = p; ++ } ++ ++ /* we reached quota already */ ++ if (++processed >= quota) { ++ /* reschedule et_dpc()/et_poll() */ ++ et->resched = TRUE; ++ et->etc->rxquota++; ++ break; ++ } ++ } ++ ++ /* prefetch the headers */ ++ if (h != NULL) { ++#ifdef CONFIG_BCM_IPROC_GMAC_PREFETCH ++ prefetch_range(PKTDATA(osh, h), SKB_DATA_PREFETCH_LEN); ++#else ++ ETPREFHDRS(PKTDATA(osh, h), PREFSZ); ++#endif ++ } ++ ++ /* post more rx bufs */ ++ (*chops->rxfill)(ch); ++ ++ while ((p = h) != NULL) { ++ h = PKTLINK(h); ++ PKTSETLINK(p, NULL); ++ ++ /* prefetch the headers */ ++ if (h != NULL) { ++#ifdef CONFIG_BCM_IPROC_GMAC_PREFETCH ++ prefetch_range(PKTDATA(osh, h), SKB_DATA_PREFETCH_LEN); ++#else ++ ETPREFHDRS(PKTDATA(osh, h), PREFSZ); ++#endif ++ } ++ ++ skb = PKTTONATIVE(osh, p); ++ et->etc->unchained++; ++ et_sendup(et, skb); ++ } ++ ++ return (processed); ++} ++ ++#if defined(GMAC_NAPI2_POLL) ++static int BCMFASTPATH ++et_poll(struct napi_struct *napi, int budget) ++{ ++ int quota = budget; ++ struct net_device *dev = napi->dev; ++ et_info_t *et = ET_INFO(dev); ++ ++#elif defined(GMAC_NAPI_POLL) ++static int BCMFASTPATH ++et_poll(struct net_device *dev, int *budget) ++{ ++ int quota = min(RXBND, *budget); ++ et_info_t *et = ET_INFO(dev); ++#else /* GMAC_NAPI_POLL */ ++static void BCMFASTPATH ++et_dpc(ulong data) ++{ ++ et_info_t *et = (et_info_t *)data; ++ int quota = RXBND; ++#endif /* GMAC_NAPI_POLL */ ++ struct chops *chops; ++ void *ch; ++ osl_t *osh; ++ uint nrx = 0; ++ ++ chops = et->etc->chops; ++ ch = et->etc->ch; ++ osh = et->etc->osh; ++ ++ ET_TRACE(("et%d: et_dpc: events 0x%x\n", et->etc->unit, et->events)); ++ ET_LOG("et%d: et_dpc: events 0x%x", et->etc->unit, et->events); ++ ++#if !defined(GMAC_NAPI_POLL) && !defined(GMAC_NAPI2_POLL) ++ ET_LOCK(et); ++#endif /* ! NAPIx_POLL */ ++ ++ if (!et->etc->up) { ++ goto done; ++ } ++ ++ /* get interrupt condition bits again when dpc was rescheduled */ ++ if (et->resched) { ++ et->events = (*chops->getintrevents)(ch, FALSE); ++ et->resched = FALSE; ++ } ++ ++ if (et->events & INTR_RX) { ++ nrx = et_rxevent(osh, et, chops, ch, quota); ++ } ++ ++ if (et->events & INTR_TX) { ++ (*chops->txreclaim)(ch, FALSE); ++ } ++ ++ (*chops->rxfill)(ch); ++ ++ /* handle error conditions, if reset required leave interrupts off! */ ++ if (et->events & INTR_ERROR) { ++ if ((*chops->errors)(ch)) { ++ printk("%s error, calling et_init() for et%d\n", __FUNCTION__, et->etc->unit); ++ et_init(et, ET_INIT_INTROFF); ++ } else { ++ if (nrx < quota) { ++ nrx += et_rxevent(osh, et, chops, ch, quota); ++ } ++ } ++ } ++ ++ /* run the tx queue */ ++ if (et->etc->txq_state != 0) { ++ if (!ET_ALL_PASSIVE_ENAB(et)) { ++ et_sendnext(et); ++ } ++#ifdef GMAC_ALL_PASSIVE ++ else { ++#ifdef CONFIG_BCM_IPROC_GMAC_TXONCPU1 ++ schedule_work_on(1, &et->txq_task.work); ++#else ++ schedule_work(&et->txq_task.work); ++#endif ++ } ++#endif /* GMAC_ALL_PASSIVE */ ++ } ++ ++ /* clear this before re-enabling interrupts */ ++ et->events = 0; ++ ++ /* something may bring the driver down */ ++ if (!et->etc->up) { ++ et->resched = FALSE; ++ goto done; ++ } ++ ++#if !defined(GMAC_NAPI_POLL) && !defined(GMAC_NAPI2_POLL) ++#ifdef GMAC_ALL_PASSIVE ++ if (et->resched) { ++ if (!ET_ALL_PASSIVE_ENAB(et)) { ++ tasklet_schedule(&et->tasklet); ++ } else { ++ schedule_work(&et->dpc_task.work); ++ } ++ } else { ++ (*chops->intrson)(ch); ++ } ++#else /* GMAC_ALL_PASSIVE */ ++ if (et->resched) { /* there may be frames left, reschedule et_dpc() */ ++ tasklet_schedule(&et->tasklet); ++ } else { /* re-enable interrupts */ ++ (*chops->intrson)(ch); ++ } ++#endif /* GMAC_ALL_PASSIVE */ ++#endif /* ! NAPIx_POLL */ ++ ++done: ++#if defined(GMAC_NAPI_POLL) ++ /* update number of frames processed */ ++ *budget -= nrx; ++ dev->quota -= nrx; ++ ++ ET_TRACE(("et%d: et_poll: quota %d budget %d\n", ++ et->etc->unit, dev->quota, *budget)); ++ ++ /* we got packets but no quota */ ++ if (et->resched) { ++ return (1); ++ } ++ ++ netif_rx_complete(dev); ++ ++ /* enable interrupts now */ ++ (*chops->intrson)(ch); ++ ++ /* indicate that we are done */ ++ return (0); ++#elif defined(GMAC_NAPI2_POLL) ++ ET_TRACE(("et%d: et_poll: budget %d\n", ++ et->etc->unit, budget)); ++ ++ /* we got packets but no quota */ ++ if (et->resched) { ++ return (1); ++ } ++ ++ napi_complete(napi); ++ ++ /* enable interrupts now */ ++ (*chops->intrson)(ch); ++ ++ /* indicate that we are done */ ++ return (0); ++#else /* !defined(GMAC_NAPI_POLL) && !defined(GMAC_NAPI2_POLL) */ ++ ET_UNLOCK(et); ++ return; ++#endif ++} ++ ++#ifdef GMAC_ALL_PASSIVE ++static void BCMFASTPATH ++et_dpc_work(struct et_task *task) ++{ ++#if !defined(GMAC_NAPI_POLL) && !defined(GMAC_NAPI2_POLL) ++ et_info_t *et = (et_info_t *)task->context; ++ et_dpc((unsigned long)et); ++#else ++ BUG_ON(1); ++#endif ++ return; ++} ++#endif /* GMAC_ALL_PASSIVE */ ++ ++static void ++et_error(et_info_t *et, struct sk_buff *skb, void *rxh) ++{ ++ uchar eabuf[32]; ++ struct ether_header *eh; ++ ++ eh = (struct ether_header *)skb->data; ++ bcm_ether_ntoa((struct ether_addr *)eh->ether_shost, eabuf); ++ ++ if (RXH_OVERSIZE(et->etc, rxh)) { ++ ET_ERROR(("et%d: rx: over size packet from %s\n", et->etc->unit, eabuf)); ++ } ++ if (RXH_CRC(et->etc, rxh)) { ++ ET_ERROR(("et%d: rx: crc error from %s\n", et->etc->unit, eabuf)); ++ } ++ if (RXH_OVF(et->etc, rxh)) { ++ ET_ERROR(("et%d: rx: fifo overflow\n", et->etc->unit)); ++ } ++ if (RXH_NO(et->etc, rxh)) { ++ ET_ERROR(("et%d: rx: crc error (odd nibbles) from %s\n", ++ et->etc->unit, eabuf)); ++ } ++ if (RXH_RXER(et->etc, rxh)) { ++ ET_ERROR(("et%d: rx: symbol error from %s\n", et->etc->unit, eabuf)); ++ } ++} ++ ++static void BCMFASTPATH ++et_sendup(et_info_t *et, struct sk_buff *skb) ++{ ++ etc_info_t *etc; ++ void *rxh; ++ uint16 flags; ++#ifdef DBG_PRINT_PKT ++ int idx; ++#endif /* DBG_PRINT_PKT */ ++#ifdef CONFIG_BCM_IPROC_GMAC_PREFETCH ++ struct sk_buff *next; ++#endif /* CONFIG_BCM_IPROC_GMAC_PREFETCH */ ++ ++ etc = et->etc; ++ ++ /* packet buffer starts with rxhdr */ ++ rxh = skb->data; ++ ++ /* strip off rxhdr */ ++ __skb_pull(skb, HWRXOFF); ++ ++ ET_TRACE(("et%d: et_sendup: %d bytes\n", et->etc->unit, skb->len)); ++ ET_LOG("et%d: et_sendup: len %d", et->etc->unit, skb->len); ++ ++ etc->rxframe++; ++ etc->rxbyte += skb->len; ++ ++ /* eh should now be aligned 2-mod-4 */ ++ ASSERT(((ulong)skb->data & 3) == 2); ++ ++ /* strip off crc32 */ ++ __skb_trim(skb, skb->len - ETHER_CRC_LEN); ++ ++ ET_PRHDR("rx", (struct ether_header *)skb->data, skb->len, etc->unit); ++ ET_PRPKT("rxpkt", skb->data, skb->len, etc->unit); ++ ++#ifdef DBG_PRINT_PKT ++ printk("et%d: rxpkt len(0x%x) tag:0x%02x%02x%02x%02x\n", etc->unit, skb->len, ++ skb->data[12], skb->data[13], skb->data[14], skb->data[15]); ++ ++ printk("et%d: %s len(0x%x) rxpkt:", etc->unit, __FUNCTION__, skb->len); ++ for (idx = 0; idx < skb->len; idx++) { ++ if ((idx % 16) == 0) { ++ printk("\n"); ++ } ++ printk("%02x ", skb->data[idx]); ++ } ++ printk("\n"); ++#endif /* DBG_PRINT_PKT */ ++ ++ /* get the error flags */ ++ flags = RXH_FLAGS(etc, rxh); ++ ++ /* check for reported frame errors */ ++ if (flags) { ++ goto err; ++ } ++ ++ skb->dev = et->dev; ++ ++ ASSERT(!PKTISCHAINED(skb)); ++ ++ /* extract priority from payload and store it out-of-band ++ * in skb->priority ++ */ ++ if (et->etc->qos) { ++ pktsetprio(skb, TRUE); ++ } ++ ++ skb->protocol = eth_type_trans(skb, et->dev); ++ ++#ifdef CONFIG_BCM_IPROC_GMAC_PREFETCH ++ next = skb->next; ++ while (1) { ++ if (next != NULL) { ++ ++ prefetch_range(next, SKB_PREFETCH_LEN); ++ next = next->next; ++ } else { ++ break; ++ } ++ } ++#endif /* CONFIG_BCM_IPROC_GMAC_PREFETCH */ ++ ++ /* send it up */ ++#if defined(GMAC_NAPI_POLL) || defined(GMAC_NAPI2_POLL) ++#ifdef CONFIG_IPROC_2STAGE_RX ++ if (!et->rxinisr) { ++ netif_receive_skb(skb); ++ } else { ++ netif_rx(skb); ++ } ++#else /* CONFIG_IPROC_2STAGE_RX */ ++ if (et->dev->features & NETIF_F_GRO) { ++ skb->ip_summed = CHECKSUM_UNNECESSARY; ++ if (skb->protocol == cpu_to_be16(ETH_P_8021Q)) { ++ skb = vlan_untag(skb); ++ if (unlikely(!skb)) { ++ goto err; ++ } ++ } ++ napi_gro_receive(&et->napi_poll, skb); ++ } else { ++ netif_receive_skb(skb); ++ } ++#endif /* CONFIG_IPROC_2STAGE_RX */ ++#else ++ netif_rx(skb); ++#endif /* defined(GMAC_NAPI_POLL) || defined(GMAC_NAPI2_POLL) */ ++ ++ ET_LOG("et%d: et_sendup ret", et->etc->unit, 0); ++ ++ return; ++ ++err: ++ et_error(et, skb, rxh); ++ ++ PKTFRMNATIVE(etc->osh, skb); ++ PKTFREE(etc->osh, skb, FALSE); ++ ++ return; ++} ++ ++static void ++et_dumpet(et_info_t *et, struct bcmstrbuf *b) ++{ ++ bcm_bprintf(b, "et %p dev %p name %s tbusy %d txq[0].qlen %d malloced %d\n", ++ et, et->dev, et->dev->name, (uint)netif_queue_stopped(et->dev), et->txq[0].qlen, ++ MALLOCED(et->osh)); ++} ++ ++void ++et_dump(et_info_t *et, struct bcmstrbuf *b) ++{ ++/* bcm_bprintf(b, "et%d: %s %s version %s\n", et->etc->unit, ++ __DATE__, __TIME__, EPI_VERSION_STR); ++*/ ++ bcm_bprintf(b, "et%d: version %s\n", et->etc->unit, EPI_VERSION_STR); ++ ++ et_dumpet(et, b); ++ etc_dump(et->etc, b); ++ ++ bcm_bprintf(b, "txdfrm(%d); txdfrmropped(%d); txqlen(%d); txqstop(%d); txdmafull(%d) txmaxlen(%d) txsgpkt(%d)\n", ++ et->etc->txfrm, et->etc->txfrmdropped, et->etc->txqlen, et->etc->txqstop, et->etc->txdmafull, ++ et->etc->txmaxlen, et->etc->txsgpkt); ++ et->etc->txfrm=0; ++ et->etc->txfrmdropped=0; ++ et->etc->txqlen=0; ++ et->etc->txqstop=0; ++ et->etc->txdmafull=0; ++ et->etc->txmaxlen=0; ++ et->etc->txsgpkt=0; ++ ++ bcm_bprintf(b, "rxquota(%d); rxdmastopped(%d)\n", ++ et->etc->rxquota, et->etc->rxdmastopped); ++ et->etc->rxquota=0; ++ et->etc->rxdmastopped=0; ++#ifdef GMAC_RATE_LIMITING ++ bcm_bprintf(b, "rxd_dropped_packets(%d)\n", ++ et->etc->rl_dropped_packets); ++ et->etc->rl_dropped_packets=0; ++#endif /* GMAC_RATE_LIMITING */ ++ ++} ++ ++void ++et_link_up(et_info_t *et) ++{ ++ ET_ERROR(("et%d: link up (%d%s)\n", ++ et->etc->unit, et->etc->speed, (et->etc->duplex? "FD" : "HD"))); ++ printk(KERN_DEBUG "et%d Link Up: %d%s\n", et->etc->unit, et->etc->speed, et->etc->duplex?"FD":"HD"); ++ netif_carrier_on(et->dev); ++} ++ ++void ++et_link_down(et_info_t *et) ++{ ++ ET_ERROR(("et%d: link down\n", et->etc->unit)); ++ printk(KERN_DEBUG "et%d Link Down\n", et->etc->unit); ++ netif_carrier_off(et->dev); ++} ++ ++bool ++et_is_link_up(et_info_t *et) ++{ ++ return netif_carrier_ok(et->dev); ++} ++ ++/********************************************************************** ++ * iproc_gmac_drv_probe(device) ++ * ++ * The Platform Driver Probe function. ++ * ++ * Input parameters: ++ * device: The Device Context ++ * ++ * Return value: ++ * 0: Driver Probe is Succesful ++ * not 0: ERROR ++ **********************************************************************/ ++static int iproc_gmac_drv_probe(struct platform_device* pldev) ++{ ++ struct net_device *dev = NULL; ++ osl_t *osh = NULL; ++ et_info_t *et = NULL; ++ int unit = et_found; ++ int err = 0; ++ unsigned char devname[8] = {0}; ++ char name[128]; ++ int idx; ++ struct device_node *np = pldev->dev.of_node; ++ const void *macaddr; ++ ++ printk("%s enter :%s; id:0x%x; unit:%d\n", __FUNCTION__, pldev->name, pldev->id, unit); ++ ++ /* Validation of platform device structure */ ++ if (!pldev) { ++ ET_ERROR(("WRONG INPUT\nplatfrom_device pointer should not be NULL.\n")); ++ return -EINVAL; ++ } ++ ++ et_found++; ++ ++ macaddr = of_get_mac_address(np); ++ if (!macaddr) { ++ dev_err(&pldev->dev, "can't find MAC address\n"); ++ return -ENODEV; ++ } ++ ++ osh = osl_attach(pldev, PCI_BUS, FALSE); ++ ASSERT(osh); ++ ++ ET_TRACE(("%s call alloc_etherdev\n", __FUNCTION__)); ++ if ((dev = alloc_etherdev(sizeof( et_info_t ))) == NULL) { ++ ET_ERROR(("%s: alloc_etherdev() failed\n", __FUNCTION__)); ++ err = -ENOMEM; ++ goto exit; ++ } ++ ++ et = ET_INFO(dev); ++ bzero(et, sizeof(et_info_t)); /* Is this needed in 2.6.36 ? -LR */ ++ et->dev = dev; ++ et->osh = osh; ++ ++ dev->base_addr = (unsigned long)of_iomap(np, 0); ++ dev->irq = (unsigned int)irq_of_parse_and_map(np, 0); ++ ++ printk("et%d: base_addr (0x%x) irq (%d)\n", unit, (uint32)dev->base_addr, dev->irq); ++ ++ if ((et->regsva = ioremap_nocache(dev->base_addr, 0xc00)) == NULL) { ++ ET_ERROR(("et%d: ioremap() failed\n", unit)); ++ err = -ENOMEM; ++ goto exit; ++ } ++ ET_TRACE(("%s base_addr: 0x%x; regsva:0x%x\n", __FUNCTION__, (uint32)dev->base_addr, (uint32)et->regsva)); ++ ++ pldev->id = dev->base_addr; ++ dev_set_drvdata(&(pldev->dev), dev); ++ SET_NETDEV_DEV(dev, (&pldev->dev)); ++ ++ init_MUTEX(&et->sem); ++ spin_lock_init(&et->lock); ++ spin_lock_init(&et->txq_lock); ++ spin_lock_init(&et->tx_lock); ++ spin_lock_init(&et->isr_lock); ++ ++ for (idx = 0; idx < NUMTXQ; idx++) { ++ skb_queue_head_init(&et->txq[idx]); ++ } ++ ++ /* Common load-time initialization */ ++ et->etc = etc_attach((void *)et, VENDOR_BROADCOM, BCMIPROC_CHIP_ID, unit, osh, et->regsva); ++ if (et->etc == NULL) { ++ ET_ERROR(("et%d: etc_attach() failed\n", unit)); ++ err = -ENOMEM; ++ goto exit; ++ } ++ ++ ether_addr_copy(dev->dev_addr, macaddr); ++ bcopy(macaddr, (char *)&et->etc->cur_etheraddr, ETHER_ADDR_LEN); ++ ++ /* init 1 second watchdog timer */ ++ init_timer(&et->timer); ++ et->timer.data = (ulong)dev; ++ et->timer.function = et_watchdog; ++ ++#if defined(CONFIG_IPROC_SDK_MGT_PORT_HANDOFF) ++#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) ++ /* schedule one second watchdog timer */ ++ et->timer.expires = jiffies + HZ; ++ add_timer(&et->timer); ++ et->set = TRUE; ++#endif /* (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) */ ++#endif /* defined(CONFIG_IPROC_SDK_MGT_PORT_HANDOFF) */ ++ ++#ifdef GMAC_RATE_LIMITING ++ /* Init 1 second watchdog timer */ ++ init_timer(&et->etc->rl_timer); ++ et->etc->rl_timer.data = (ulong)dev; ++ et->etc->rl_timer.function = et_release_congestion; ++#endif /* GMAC_RATE_LIMITING */ ++ ++#ifdef GMAC_ALL_PASSIVE ++ if (ET_ALL_PASSIVE_ENAB(et)) { ++ MY_INIT_WORK(&et->dpc_task.work, (work_func_t)et_dpc_work); ++ et->dpc_task.context = et; ++ MY_INIT_WORK(&et->txq_task.work, (work_func_t)et_txq_work); ++ et->txq_task.context = et; ++ } ++ if (et_ctf_pipeline_loopback(et)) { ++ et->all_dispatch_mode = FALSE; ++ } else { ++ et->all_dispatch_mode = (passivemode == 0) ? TRUE : FALSE; ++ } ++#endif /* GMAC_ALL_PASSIVE */ ++ ++ ET_TRACE(("%s request irq\n", __FUNCTION__)); ++ /* register our interrupt handler */ ++ if (request_irq(dev->irq, et_isr, IRQF_SHARED, dev->name, et)) { ++ ET_ERROR(("%s: request_irq(%d) failed\n", __FUNCTION__, dev->irq)); ++ err = -ENOMEM; ++ goto exit; ++ } ++ ++ /* add us to the global linked list */ ++ et->next = et_list; ++ et_list = et; ++ ++#ifdef HAVE_NET_DEVICE_OPS ++ dev->netdev_ops = &et_netdev_ops ; ++#else /* HAVE_NET_DEVICE_OPS */ ++ dev->open = et_open; ++ dev->stop = et_close; ++ dev->hard_start_xmit = et_start; ++ dev->get_stats = et_get_stats; ++ dev->set_mac_address = et_set_mac_address; ++ dev->set_multicast_list = et_set_multicast_list; ++ dev->do_ioctl = et_ioctl; ++#endif /* HAVE_NET_DEVICE_OPS */ ++ ++#if defined(GMAC_NAPI_POLL) ++ dev->poll = et_poll; ++ dev->weight = (ET_GMAC(et->etc) ? 64 : 32); ++#elif defined(GMAC_NAPI2_POLL) ++ netif_napi_add(dev, & et->napi_poll, et_poll, 64); ++ napi_enable(&et->napi_poll); ++#else /* !GMAC_NAPI_POLL && !GMAC_NAPI2_POLL */ ++ /* Setup the bottom half handler */ ++ tasklet_init(&et->tasklet, et_dpc, (ulong)et); ++#endif ++ ++#if defined(BCMDMASGLISTOSL) ++ dev->features = (NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_ALL_CSUM); ++ dev->vlan_features = (NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_ALL_CSUM); ++ ++#ifdef CONFIG_BCM_GRO_ENABLE ++ dev->features |= NETIF_F_GRO; ++ dev->vlan_features |= NETIF_F_GRO; ++ printk("et%d: Enable Checksum-SG-GRO\n", unit); ++#endif /* CONFIG_BCM_GRO_ENABLE */ ++#endif /* BCMDMASGLISTOSL */ ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) ++ dev->ethtool_ops = &et_ethtool_ops; ++#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) */ ++ ++ /* Assign netdev name consistently, even if GMAC0 or 1 is disabled */ ++ snprintf(devname, 8, "eth%d", unit); ++ dev_alloc_name(dev, devname); ++ ++ ET_TRACE(("%s register netdev\n", __FUNCTION__)); ++ if (register_netdev(dev)) { ++ ET_ERROR(("%s register_netdev() failed\n", __FUNCTION__)); ++ err = -ENOMEM; ++ goto exit; ++ } ++ ++ /* Print hello string */ ++ (*et->etc->chops->longname)(et->etc->ch, name, sizeof(name)); ++ printk("%s: %s %s\n", dev->name, name, EPI_VERSION_STR); ++ ++ eth_mac_proc_create(dev); ++ ++ ET_TRACE(("%s: exit\n", __FUNCTION__)); ++ ++ return 0; ++ ++exit: ++#ifndef CONFIG_OF ++ if (macbase) { ++ iounmap(macbase); ++ macbase=NULL; ++ } ++ if (memres) { ++ release_mem_region(memres->start, (memres->end - memres->start + 1)); ++ memres=NULL; ++ } ++#endif ++ if (dev) { ++ free_netdev(dev); ++ dev = NULL; ++ } ++ if (osh) { ++ osl_detach(osh); ++ osh=NULL; ++ } ++ if (et) { ++ etc_detach(et->etc); ++ et->dev = NULL; ++ et->osh = NULL; ++ et_free(et); ++ et=NULL; ++ } ++ return err; ++} ++ ++ ++/********************************************************************** ++ * iproc_gmac_drv_remove(device) ++ * ++ * The Removal of Platform Device, and un-initialize the previously ++ * added MAC, and it's MEM Regions and Resources. ++ * ++ * Input parameters: ++ * device: The Device Context ++ * ++ * Return value: ++ * 0: Driver Entry is Succesfull ++ **********************************************************************/ ++static int __exit iproc_gmac_drv_remove(struct platform_device *pldev) ++{ ++ struct net_device *dev = platform_get_drvdata(pldev); ++ int retVal = 0; ++ et_info_t *et = NULL; ++ struct resource *memres = NULL; ++ ++ ET_TRACE(("%s: enter\n", __FUNCTION__)); ++ printk("%s: enter\n", __FUNCTION__); ++ ++#ifdef CONFIG_PM ++ iproc_gmac_drv_suspend(pldev, PMSG_SUSPEND); ++#endif ++ ++ et = ET_INFO(dev); ++ ++ iounmap(et->regsva); ++ unregister_netdev(dev); ++ ++ memres = platform_get_resource(pldev, IORESOURCE_MEM, 0); ++ if (memres) { ++ release_mem_region(memres->start, (memres->end - memres->start + 1)); ++ } else { ++ ET_ERROR(("ERROR: Could not get Platform Resource GMAC Register Memory Resource\n")); ++ retVal = -ENOMEM; ++ } ++ ++ free_netdev(dev); ++ ++#ifdef CONFIG_OF ++ eth_mac_proc_remove (dev); ++#endif ++ ++ et->dev = NULL; ++ et_free(et); ++ ++ ET_TRACE(("%s: exit\n", __FUNCTION__)); ++ ++ return retVal; ++} ++ ++#ifdef CONFIG_PM ++static int iproc_gmac_drv_suspend(struct platform_device *pdev, pm_message_t state) ++{ ++ int ret; ++ char *filename = "/usr/sbin/ifdown"; ++ char *argv[] = {filename, "eth0", NULL}; ++ char *envp[] = {"HOME=/", ++ "TERM=linux", ++ "PATH=/sbin:/usr/sbin:/bin:/usr/bin", ++ NULL}; ++ ++ ET_TRACE(("%s: enter\n", __FUNCTION__)); ++ printk("%s: enter\n", __FUNCTION__); ++ ++/* ret = kernel_execve(filename, (const char * const*) argv, (const char * const*) envp);*/ ++ ret = do_execve(getname_kernel(filename), (const char *const *)argv, (const char *const *)envp); ++ ET_TRACE(("%s: exit\n", __FUNCTION__)); ++ ++ return 0; ++} ++ ++static int iproc_gmac_drv_resume(struct platform_device *pdev) ++{ ++ int ret; ++ char *filename = "/usr/sbin/ifup"; ++ char *argv[] = {filename, "eth0", NULL}; ++ char *envp[] = {"HOME=/", ++ "TERM=linux", ++ "PATH=/sbin:/usr/sbin:/bin:/usr/bin", ++ NULL}; ++ ++ ET_TRACE(("%s: enter\n", __FUNCTION__)); ++ printk("%s: enter\n", __FUNCTION__); ++ /*ret = kernel_execve(filename, (const char * const*) argv, (const char * const*) envp);*/ ++ ret = do_execve(getname_kernel(filename), (const char *const *)argv, (const char *const *)envp); ++ ++ ET_TRACE(("%s: exit\n", __FUNCTION__)); ++ ++ return 0; ++} ++#endif /* CONFIG_PM */ ++ ++ ++/********************************************************************** ++ * iproc_gmac_init_module(VOID) ++ * ++ * The Driver Entry Function ++ * ++ * Input parameters: ++ * None ++ * ++ * Return value: ++ * 0: Driver Entry is Succesful ++ * not 0: ERROR ++ **********************************************************************/ ++static int __init ++iproc_gmac_init_module(void) ++{ ++ ET_TRACE(("%s: enter\n", __FUNCTION__)); ++ ++#ifdef BCMDBG ++ if (msglevel != 0xdeadbeef) { ++ et_msg_level = msglevel; ++ } else { ++ char *var = getvar(NULL, "et_msglevel"); ++ if (var) { ++ et_msg_level = bcm_strtoul(var, NULL, 0); ++ } ++ } ++ ++ printk("%s: msglevel set to 0x%x\n", __FUNCTION__, et_msg_level); ++#endif /* BCMDBG */ ++ ++#ifdef GMAC_ALL_PASSIVE ++ { ++ char *var = getvar(NULL, "et_dispatch_mode"); ++ if (var) ++ passivemode = bcm_strtoul(var, NULL, 0); ++ printk("%s: passivemode set to 0x%x\n", __FUNCTION__, passivemode); ++ } ++#endif /* GMAC_ALL_PASSIVE */ ++ ++#ifdef GMAC_NAPI_POLL ++ printk("%s: GMAC_NAPI_POLL mode\n", __FUNCTION__); ++#endif /* GMAC_NAPI_POLL */ ++ ++#ifdef GMAC_NAPI2_POLL ++ printk("%s: GMAC_NAPI2_POLL mode\n", __FUNCTION__); ++#endif /* GMAC_NAPI2_POLL */ ++ ++#ifdef ET_LIMIT_TXQ ++ { ++ char *var = getvar(NULL, "et_txq_thresh"); ++ if (var) { ++ et_txq_thresh = bcm_strtoul(var, NULL, 0); ++ } ++ printk("%s: et_txq_thresh set to 0x%x\n", __FUNCTION__, et_txq_thresh); ++ } ++#endif /* ET_LIMIT_TXQ */ ++ ++#ifdef GMAC_RATE_LIMITING ++ { ++ char *var = getvar(NULL, "et_rx_rate_limit"); ++ if (var) { ++ et_rx_rate_limit = bcm_strtoul(var, NULL, 0); ++ } ++ printk("%s: et_rx_rate_limit set to 0x%x\n", __FUNCTION__, et_rx_rate_limit); ++ } ++#endif /* GMAC_RATE_LIMITING */ ++ ++ ET_TRACE(("%s: exit\n", __FUNCTION__)); ++ return 0; ++} ++ ++ ++#ifndef CONFIG_OF ++/********************************************************************** ++ * iproc_gmac_cleanup_module(VOID) ++ * ++ * The Driver Exit Function ++ * ++ * Input parameters: ++ * None ++ * ++ * Return value: ++ * Nothing ++ **********************************************************************/ ++static void __exit ++iproc_gmac_cleanup_module(void) ++{ ++ int idx; ++ ++ ET_TRACE(("%s: enter\n", __FUNCTION__)); ++ ++ for (idx = 0; idx < IPROC_NUM_GMACS; idx++) { ++ if (gmac_pdev_loaded[idx]) { ++ /* Unregister GMAC driver */ ++ iproc_platform_driver_unregister(&gmac_pdrv[idx]); ++ } ++ } ++ ++ /* Clean up the proc directory */ ++ eth_mac_proc_remove(); ++ ++ ET_TRACE(("%s: exit\n", __FUNCTION__)); ++ return; ++} ++#endif /*CONFIG_OF*/ ++ ++#if 0 ++static int get_fa_bypass(char *page, char **start, off_t off, int count, int *eof, void *data) ++{ ++ unsigned int len=0; ++ len += sprintf(page+len, "\n\n## Current FA Bypass setting = 0x%x, %s ##\n\n",gBypass, gBypass?"enabled":"disabled"); ++ *eof = 1; ++ return len; ++} ++ ++static int set_fa_bypass(struct file *file, const char *buffer, unsigned long count, void *data) ++{ ++ unsigned int len=1; ++ unsigned char debug_buffer[2]; ++ int bypass =0; ++ ++ if (count != 2) { ++ ET_ERROR(("Please pass (one:1) digit FA bypass value only, 0=disable FA bypass, 1 = enable FA bypass\n")); ++ return -EINVAL; ++ } ++ ++ /* Last buffer byte will be LF or CR only */ ++ if(copy_from_user(&debug_buffer[0], buffer, len)) { ++ ET_ERROR(("Problem in copying invalid user buffer\n")); ++ return -EFAULT; ++ } ++ ++ debug_buffer[len]='\0'; /* Only one byte value is available now */ ++ if ( sscanf(debug_buffer,"%d",&bypass) != 1) { ++ ET_ERROR(("\n##Invalid value :%s: is passed ##\n",debug_buffer)); ++ return -EINVAL; ++ } ++ if (!((bypass >=DISABLE_FA_BYPASS) && (bypass <= ENABLE_FA_BYPASS))) { ++ ET_ERROR(("\n##Passed value :%d: is not in valid range %d-%d \n",bypass,DISABLE_FA_BYPASS,ENABLE_FA_BYPASS)); ++ return -EINVAL; ++ } ++ ET_TRACE(("\n##set_fa_bypass(): Previous: 0x%x %s ##\n", gBypass, gBypass?"enabled":"disabled")); ++ gBypass = bypass; ++ ET_TRACE(("\n##set_fa_bypass(): New: 0x%x %s ##\n", gBypass, gBypass?"enabled":"disabled")); ++ return count; ++} ++#endif ++ ++static char* iproc_eth_proc_root="iproc_eth"; ++static struct proc_dir_entry *iproc_eth_root_dir=NULL; // BCM5892 eth proc root directory ++static int eth_mac_proc_create(struct net_device *dev ) ++{ ++/* struct proc_dir_entry *dent, *ent;*/ ++ struct proc_dir_entry *dent; ++ et_info_t *et = NULL; ++ etc_info_t *etc = NULL; ++ char fname[32]; ++ ++ et = ET_INFO(dev); ++ if (et != NULL) { ++ etc = et->etc; ++ } ++ ++ if ((et == NULL) || (etc == NULL)) { ++ printk("%s: error: Unit probably not initialized by probe function." ++ " et=0x%pm etc=0x%p\n", __FUNCTION__, et, etc); ++ return -1; ++ } ++ ++ ET_TRACE(("%s: enter\n", __FUNCTION__)); ++ ++ snprintf(fname, 32, "%s%u", iproc_eth_proc_root, etc->unit); ++ ++ dent = proc_mkdir(fname,iproc_eth_root_dir); ++#if 0 ++ if (dent) { ++ /* unit 2 has FA connectivity, create bypass path only for unit 2 */ ++ if (etc->unit == 2) { ++ printk("\nCreating fa bypass proc entry\n"); ++ ++ ent = create_proc_entry("fa_bypass", S_IFREG|S_IRUGO, dent); ++ if (ent) { ++ ent->read_proc = get_fa_bypass; ++ ent->write_proc = set_fa_bypass; ++ } else { ++ printk("Error creating proc_entry, returning\n"); ++ return -1; ++ } ++ } ++ } ++#endif ++ ET_TRACE(("%s: exit\n", __FUNCTION__)); ++ return 0; ++} ++ ++#ifndef CONFIG_OF ++static void eth_mac_proc_remove(void) ++{ ++ ET_TRACE(("%s: enter\n", __FUNCTION__)); ++ printk("%s: enter\n", __FUNCTION__); ++ remove_proc_entry(iproc_eth_proc_root,NULL); ++ ET_TRACE(("%s: exit\n", __FUNCTION__)); ++} ++#else ++static void eth_mac_proc_remove(struct net_device *dev) ++{ ++ et_info_t *et; ++ etc_info_t *etc; ++ char fname[32]; ++ ++ ET_TRACE(("%s: enter\n", __FUNCTION__)); ++ printk("%s: enter\n", __FUNCTION__); ++ ++ et = ET_INFO(dev); ++ if (et == NULL) { ++ printk("%s: error: Unit probably not initialized by probe function.\n", __FUNCTION__); ++ return; ++ } ++ ++ etc = et->etc; ++ if (etc == NULL) { ++ printk("%s: error: Unit probably not initialized by probe \ ++ function.\n", __FUNCTION__); ++ return; ++ } ++ ++ snprintf(fname, 32, "%s%u", iproc_eth_proc_root, etc->unit); ++ remove_proc_entry(fname,NULL); ++ ++ ET_TRACE(("%s: exit\n", __FUNCTION__)); ++} ++#endif /* CONFIG_OF */ ++ ++#ifdef CONFIG_OF ++static const struct of_device_id brcm_iproc_dt_ids[] = { ++ { .compatible = "brcm,iproc-gmac"}, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, brcm_iproc_dt_ids); ++ ++static struct platform_driver iproc_gmac_driver = ++{ ++ .probe = iproc_gmac_drv_probe, ++ .remove = __exit_p(iproc_gmac_drv_remove), ++ .suspend = iproc_gmac_drv_suspend, ++ .resume = iproc_gmac_drv_resume, ++ .driver = ++ { ++ .name = "bcmiproc-gmac", ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(brcm_iproc_dt_ids), ++ }, ++}; ++module_init(iproc_gmac_init_module); ++module_platform_driver(iproc_gmac_driver); ++#else ++module_init(iproc_gmac_init_module); ++module_exit(iproc_gmac_cleanup_module); ++#endif /*CONFIG_OF*/ ++ ++MODULE_DESCRIPTION("Broadcom Northstar Ethernet Driver"); ++MODULE_LICENSE("GPL"); +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_linux.h b/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_linux.h +--- a/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_linux.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_linux.h 2017-11-09 17:53:43.900292000 +0800 +@@ -0,0 +1,50 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ * ++ * Linux device driver tunables for ++ * Broadcom BCM47XX 10/100Mbps Ethernet Device Driver ++ * ++ * $Id: et_linux.h 320789 2012-03-13 04:01:27Z rnuti $ ++ */ ++ ++#ifndef _et_linux_h_ ++#define _et_linux_h_ ++ ++/* tunables */ ++#define NTXD 512 /* # tx dma ring descriptors (must be ^2) */ ++#define NRXD 512 /* # rx dma ring descriptors (must be ^2) */ ++#if defined(CONFIG_RAM_SIZE) && (CONFIG_RAM_SIZE <= 16) ++#define NRXBUFPOST 256 /* try to keep this # rbufs posted to the chip */ ++#else ++#define NRXBUFPOST 420 /* try to keep this # rbufs posted to the chip */ ++#endif ++#ifdef CONFIG_JUMBO_FRAME ++#define BCM_ETHER_MAX_LEN 2500 ++#define RXBUFSZ (BCM_ETHER_MAX_LEN + HWRXOFF + BCMEXTRAHDROOM) /* receive buffer size */ ++#else ++#define BCM_ETHER_MAX_LEN 1518 //ETHER_MAX_LEN (1518) ++#define RXBUFSZ 1792 ++#endif /* CONFIG_JUMBO_FRAME */ ++ ++ ++#ifndef RXBND ++#define RXBND 64 //32 /* max # rx frames to process in dpc */ ++#endif ++ ++#if defined(ILSIM) || defined(__arch_um__) ++#undef NTXD ++#define NTXD 16 ++#undef NRXD ++#define NRXD 16 ++#undef NRXBUFPOST ++#define NRXBUFPOST 2 ++#endif ++ ++#define PKTCBND 48 ++ ++#define CTFPOOLSZ 768 ++ ++#define PREFSZ 96 ++#define ETPREFHDRS(h, sz) OSL_PREF_RANGE_ST((h), (sz)) ++ ++#endif /* _et_linux_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/et/sys/etc.c b/drivers/net/ethernet/broadcom/gmac/src/et/sys/etc.c +--- a/drivers/net/ethernet/broadcom/gmac/src/et/sys/etc.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/et/sys/etc.c 2017-11-09 17:53:43.901298000 +0800 +@@ -0,0 +1,746 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ * ++ * Common [OS-independent] portion of ++ * Broadcom Home Networking Division 10/100 Mbit/s Ethernet ++ * Device Driver. ++ * ++ * $Id: etc.c 323634 2012-03-26 10:26:11Z groques $ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "etcgmac.h" ++ ++#ifdef BCMDBG ++uint32 et_msg_level = 1; ++#else ++uint32 et_msg_level = 0; ++#endif /* BCMDBG */ ++uint8 ethup = 0; ++uint8 ethupmask = 0; ++etc_info_t *ethupetcptr[IPROC_NUM_GMACS]; ++ ++/* local prototypes */ ++static void etc_loopback(etc_info_t *etc, int on); ++static void etc_dumpetc(etc_info_t *etc, struct bcmstrbuf *b); ++int etc_gmac_speed(int gmac); ++ ++#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) ++extern void gmac_set_amac_mdio(int en); ++extern int gmac_has_mdio_access(void); ++#elif defined(CONFIG_MACH_WH2) ++extern void __iomem *get_iproc_wrap_ctrl_base(void); ++extern int egphy28_reg_read(uint32 phy_addr, int reg_addr, uint16 *data); ++#endif /* (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) */ ++ ++#ifdef CONFIG_SERDES_ASYMMETRIC_MODE ++void gmac_serdes_asym_mode(etc_info_t *etcptrs[]); ++#endif /* CONFIG_SERDES_ASYMMETRIC_MODE */ ++ ++/* 802.1d priority to traffic class mapping. queues correspond one-to-one ++ * with traffic classes. ++ */ ++uint32 up2tc[NUMPRIO] = { ++ TC_BE, /* 0 BE TC_BE Best Effort */ ++ TC_BK, /* 1 BK TC_BK Background */ ++ TC_BK, /* 2 -- TC_BK Background */ ++ TC_BE, /* 3 EE TC_BE Best Effort */ ++ TC_CL, /* 4 CL TC_CL Controlled Load */ ++ TC_CL, /* 5 VI TC_CL Controlled Load */ ++ TC_VO, /* 6 VO TC_VO Voice */ ++ TC_VO /* 7 NC TC_VO Voice */ ++}; ++ ++uint32 priq_selector[] = { ++ [0x0] = TC_NONE, [0x1] = TC_BK, [0x2] = TC_BE, [0x3] = TC_BE, ++ [0x4] = TC_CL, [0x5] = TC_CL, [0x6] = TC_CL, [0x7] = TC_CL, ++ [0x8] = TC_VO, [0x9] = TC_VO, [0xa] = TC_VO, [0xb] = TC_VO, ++ [0xc] = TC_VO, [0xd] = TC_VO, [0xe] = TC_VO, [0xf] = TC_VO ++}; ++ ++/* find the chip opsvec for this chip */ ++struct chops* ++etc_chipmatch(uint vendor, uint device) ++{ ++ extern struct chops bcmgmac_et_chops; ++ ++ if (bcmgmac_et_chops.id(vendor, device)) { ++ return (&bcmgmac_et_chops); ++ } ++ ++ return (NULL); ++} ++ ++void* ++etc_attach(void *et, uint vendor, uint device, uint unit, void *osh, void *regsva) ++{ ++ etc_info_t *etc; ++ char *var; ++ ++ ET_TRACE(("et%d: etc_attach: vendor 0x%x device 0x%x\n", unit, vendor, device)); ++ ++ /* some code depends on packed structures */ ++ ASSERT(sizeof(struct ether_addr) == ETHER_ADDR_LEN); ++ ASSERT(sizeof(struct ether_header) == ETHER_HDR_LEN); ++ ++ /* allocate etc_info_t state structure */ ++ if ((etc = (etc_info_t*) MALLOC(osh, sizeof(etc_info_t))) == NULL) { ++ ET_ERROR(("et%d: etc_attach: out of memory, malloced %d bytes\n", unit, ++ MALLOCED(osh))); ++ return (NULL); ++ } ++ bzero((char*)etc, sizeof(etc_info_t)); ++ ++ etc->et = et; ++ etc->unit = unit; ++ etc->osh = osh; ++ etc->vendorid = (uint16) vendor; ++ etc->deviceid = (uint16) device; ++ etc->forcespeed = etc_gmac_speed(unit); ++ etc->linkstate = FALSE; ++ etc->mdio_init_time = 5; /* number of seconds to wait before release mdio bus */ ++ var = getvar(NULL, "eth_init_time"); ++ if (var) { ++ etc->mdio_init_time = bcm_strtoul(var, NULL, 0); ++ } ++ printk("%s() mdio_init_time = %d\n", __FUNCTION__, etc->mdio_init_time); ++ ethupmask |= 1<unit; ++ ethupetcptr[unit] = etc; ++ ++ /* set chip opsvec */ ++ etc->chops = etc_chipmatch(vendor, device); ++ ASSERT(etc->chops); ++ ++ /* chip attach */ ++ if ((etc->ch = (*etc->chops->attach)(etc, osh, regsva)) == NULL) { ++ ET_ERROR(("et%d: chipattach error\n", unit)); ++ goto fail; ++ } ++ ++ return ((void*)etc); ++ ++fail: ++ etc_detach(etc); ++ return (NULL); ++} ++ ++void ++etc_detach(etc_info_t *etc) ++{ ++ if (etc == NULL) ++ return; ++ ++ /* free chip private state */ ++ if (etc->ch) { ++ (*etc->chops->detach)(etc->ch); ++ etc->chops = etc->ch = NULL; ++ } ++ ++ MFREE(etc->osh, etc, sizeof(etc_info_t)); ++} ++ ++void ++etc_reset(etc_info_t *etc) ++{ ++ ET_TRACE(("et%d: etc_reset\n", etc->unit)); ++ ++ etc->reset++; ++ ++ /* reset the chip */ ++ (*etc->chops->reset)(etc->ch); ++ ++ /* free any posted tx packets */ ++ (*etc->chops->txreclaim)(etc->ch, TRUE); ++ ++#ifdef DMA ++ /* free any posted rx packets */ ++ (*etc->chops->rxreclaim)(etc->ch); ++#endif /* DMA */ ++} ++ ++void ++etc_init(etc_info_t *etc, uint options) ++{ ++ ET_TRACE(("et%d: etc_init\n", etc->unit)); ++ ++ ASSERT(etc->pioactive == NULL); ++ ASSERT(!ETHER_ISNULLADDR(&etc->cur_etheraddr)); ++ ASSERT(!ETHER_ISMULTI(&etc->cur_etheraddr)); ++ ++ /* init the chip */ ++ (*etc->chops->init)(etc->ch, options); ++ /* init the PM change mode and linkstate */ ++ etc->pm_modechange = FALSE; ++ etc->linkstate = FALSE; ++} ++ ++/* mark interface up */ ++void ++etc_up(etc_info_t *etc) ++{ ++ etc->up = TRUE; ++ ++ /* enable the port phy */ ++ (*etc->chops->phyenable)(etc->ch, etc->unit, etc->phyaddr, 1); ++ ++ et_init(etc->et, ET_INIT_FULL | ET_INIT_INTRON); ++} ++ ++/* mark interface down */ ++uint ++etc_down(etc_info_t *etc, int reset) ++{ ++ uint callback; ++ ++ callback = 0; ++ ++ ET_FLAG_DOWN(etc); ++ ++ /* disable the port phy */ ++ (*etc->chops->phyenable)(etc->ch, etc->unit, etc->phyaddr, 0); ++ ++ if (reset) { ++ et_reset(etc->et); ++ } ++ ++ /* suppress link state changes during power management mode changes */ ++ if (etc->linkstate) { ++ etc->linkstate = FALSE; ++ if (!etc->pm_modechange) { ++ et_link_down(etc->et); ++ } ++ } ++ ++ return (callback); ++} ++ ++/* common iovar handler. return 0=ok, -1=error */ ++int ++etc_iovar(etc_info_t *etc, uint cmd, uint set, void *arg) ++{ ++ int error; ++ uint *vecarg; ++ ++ error = 0; ++ vecarg = (uint *)arg; ++ ET_TRACE(("et%d: etc_iovar: cmd 0x%x\n", etc->unit, cmd)); ++ ++ switch (cmd) { ++#ifdef BCMDBG ++ case IOV_ET_CLEAR_DUMP: ++ if (set) { ++ uint size = ((char *)(&etc->rxbadlen) - (char *)(&etc->txframe)); ++ ++ bzero((char *)&etc->txframe, size + sizeof(etc->rxbadlen)); ++ (*etc->chops->dumpmib)(etc->ch, NULL, TRUE); ++ error = 0; ++ } ++ break; ++#endif /* BCMDBG */ ++ case IOV_PKTC: ++ if (set) { ++ etc->pktc = *vecarg; ++ } else { ++ *vecarg = (uint)etc->pktc; ++ } ++ break; ++ ++ case IOV_PKTCBND: ++ if (set) { ++ etc->pktcbnd = MAX(*vecarg, 32); ++ } else { ++ *vecarg = etc->pktcbnd; ++ } ++ break; ++ ++ case IOV_COUNTERS: ++ { ++ struct bcmstrbuf b; ++ bcm_binit(&b, (char*)arg, IOCBUFSZ); ++ etc_dumpetc(etc, &b); ++ } ++ break; ++ ++ default: ++ error = -1; ++ } ++ ++ return (error); ++} ++ ++/* common ioctl handler. return: 0=ok, -1=error */ ++int ++etc_ioctl(etc_info_t *etc, int cmd, void *arg) ++{ ++ int error; ++ int val; ++ int *vec = (int*)arg; ++ ++ error = 0; ++ ++ val = arg ? *(int*)arg : 0; ++ ++ ET_TRACE(("et%d: etc_ioctl: cmd 0x%x\n", etc->unit, cmd)); ++ ++ switch (cmd) { ++ case ETCUP: ++ et_up(etc->et); ++ break; ++ ++ case ETCDOWN: ++ et_down(etc->et, TRUE); ++ break; ++ ++ case ETCLOOP: ++ etc_loopback(etc, val); ++ break; ++ ++ case ETCDUMP: ++ if (et_msg_level & 0x10000) { ++ bcmdumplog((char *)arg, IOCBUFSZ); ++ } else { ++ struct bcmstrbuf b; ++ bcm_binit(&b, (char*)arg, IOCBUFSZ); ++ et_dump(etc->et, &b); ++ } ++ break; ++ ++ case ETCSETMSGLEVEL: ++ et_msg_level = val; ++ break; ++ ++ case ETCPROMISC: ++ etc_promisc(etc, val); ++ break; ++ ++ case ETCQOS: ++ etc_qos(etc, val); ++ break; ++ ++ case ETCSPEED: ++ if (vec) { ++ if (vec[0] < ET_AUTO || vec[0] > ET_1000FULL) { ++ goto err; ++ } ++ ++ etc->forcespeed = vec[0]; ++ ++ /* explicitly reset the phy */ ++ (*etc->chops->phyreset)(etc->ch); ++ ++ /* request restart autonegotiation if we're reverting to adv mode */ ++ etc->advertise = etc->advertise2 = 0; ++ if (etc->forcespeed == ET_AUTO) { ++ if (vec[1] & ADVERTISED_10baseT_Half) { ++ etc->advertise |= ADV_10HALF; ++ } ++ if (vec[1] & ADVERTISED_10baseT_Full) { ++ etc->advertise |= ADV_10FULL; ++ } ++ if (vec[1] & ADVERTISED_100baseT_Half) { ++ etc->advertise |= ADV_100HALF; ++ } ++ if (vec[1] & ADVERTISED_100baseT_Full) { ++ etc->advertise |= ADV_100FULL; ++ } ++ if (vec[1] & ADVERTISED_1000baseT_Full) { ++ etc->advertise2 |= ADV_1000FULL; ++ } ++ etc->needautoneg = TRUE; ++ } else { ++ etc->needautoneg = FALSE; ++ } ++ et_init(etc->et, ET_INIT_INTRON); ++ } ++ break; ++ ++ case ETCPHYRD: ++ if (vec) { ++ vec[1] = (*etc->chops->phyrd)(etc->ch, etc->phyaddr, vec[0]); ++ ET_TRACE(("etc_ioctl: ETCPHYRD of reg 0x%x => 0x%x\n", vec[0], vec[1])); ++ } ++ break; ++ ++ case ETCPHYRD2: ++ if (vec) { ++ uint phyaddr, reg; ++ phyaddr = vec[0] >> 16; ++ reg = vec[0] & 0xffff; ++ vec[1] = (*etc->chops->phyrd)(etc->ch, phyaddr, reg); ++ ET_TRACE(("etc_ioctl: ETCPHYRD2 of phy 0x%x, reg 0x%x => 0x%x\n", ++ phyaddr, reg, vec[1])); ++ } ++ break; ++ ++ case ETCPHYWR: ++ if (vec) { ++ ET_TRACE(("etc_ioctl: ETCPHYWR to reg 0x%x <= 0x%x\n", vec[0], vec[1])); ++ (*etc->chops->phywr)(etc->ch, etc->phyaddr, vec[0], (uint16)vec[1]); ++ } ++ break; ++ ++ case ETCPHYWR2: ++ if (vec) { ++ uint phyaddr, reg; ++ phyaddr = vec[0] >> 16; ++ reg = vec[0] & 0xffff; ++ (*etc->chops->phywr)(etc->ch, phyaddr, reg, (uint16)vec[1]); ++ ET_TRACE(("etc_ioctl: ETCPHYWR2 to phy 0x%x, reg 0x%x <= 0x%x\n", ++ phyaddr, reg, vec[1])); ++ } ++ break; ++ ++ default: ++err: ++ error = -1; ++ } ++ ++ return (error); ++} ++ ++/* called once per second */ ++void ++etc_watchdog(etc_info_t *etc) ++{ ++ uint16 status; ++ uint16 lpa; ++ ++#if defined(CONFIG_MACH_WH2) ++ uint32 select = (ioread32(get_iproc_wrap_ctrl_base() + 0xa8)); /* IPROC_WRAP_TOP_STRAP_STATUS_1 */ ++ if (select & 0x04) /* select SGMII path */ ++ { ++ etc->speed = 1000; ++ etc->duplex = 1; ++ etc->linkstate = true; ++ (*etc->chops->duplexupd)(etc->ch); ++ return; ++ } ++#endif ++ etc->now++; ++ ++ /* no local phy registers */ ++ if (etc->phyaddr == EPHY_NOREG) ++ { ++ etc->linkstate = TRUE; ++ etc->duplex = 1; ++ /* keep emac txcontrol duplex bit consistent with current phy duplex */ ++ (*etc->chops->duplexupd)(etc->ch); ++ return; ++ } ++ ++ if (etc->up && etc->linkstate) { ++ if (!(ethup & 1<unit)) { ++ printk(KERN_DEBUG "et%d Interface up\n", etc->unit); ++ } ++ ethup |= 1<unit; ++ } ++ ++#if defined(CONFIG_IPROC_SDK_MGT_PORT_HANDOFF) ++#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) ++ if ( !gmac_has_mdio_access()) { ++ /* we can't monitor link so force link up */ ++ /* if GMAC does not have access to MDIO then exit */ ++ if (!etc->linkstate) { ++ etc->linkstate = TRUE; ++ etc->duplex = 1; ++ etc->speed = 1000; ++ } ++ /* keep emac txcontrol duplex bit consistent with current phy duplex */ ++ (*etc->chops->duplexupd)(etc->ch); ++ if (!et_is_link_up(etc->et)) { ++ printk(KERN_DEBUG "%s rcan't access PHY, forcing link up\n", __FUNCTION__); ++ et_link_up(etc->et); ++ } ++ return; ++ } ++ ++ /* check if need to release mdio access */ ++ if ((ethup==ethupmask) || (etc->now > etc->mdio_init_time)) { ++ /* either both links up or (5) "eth_init_time" seconds elapsed */ ++ /* keep mdio access if ethtool is set */ ++ char *s = getvar(NULL, "ethtool"); ++ if (!s) { ++#ifdef CONFIG_SERDES_ASYMMETRIC_MODE ++ gmac_serdes_asym_mode(ethupetcptr); ++#endif /* CONFIG_SERDES_ASYMMETRIC_MODE */ ++ printk(KERN_DEBUG "%s releasing MDIO access; ethup(0x%x)\n", __FUNCTION__, ethup); ++ gmac_set_amac_mdio(0); ++ return; ++ } ++ } ++#endif /* (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) */ ++#endif /* defined(CONFIG_IPROC_SDK_MGT_PORT_HANDOFF) */ ++ ++ status = (*etc->chops->phyrd)(etc->ch, etc->phyaddr, 1); ++ /* check for bad mdio read */ ++ if (status == 0xffff) { ++ ET_ERROR(("et%d: etc_watchdog: bad mdio read: phyaddr %d mdcport %d\n", ++ etc->unit, etc->phyaddr, etc->mdcport)); ++ return; ++ } ++ ++ if (etc->forcespeed == ET_AUTO) { ++ uint16 adv, adv2 = 0, status2 = 0, estatus; ++ ++ adv = (*etc->chops->phyrd)(etc->ch, etc->phyaddr, 4); ++ lpa = (*etc->chops->phyrd)(etc->ch, etc->phyaddr, 5); ++ ++ /* read extended status register. if we are 1000BASE-T ++ * capable then get our advertised capabilities and the ++ * link partner capabilities from 1000BASE-T control and ++ * status registers. ++ */ ++ estatus = (*etc->chops->phyrd)(etc->ch, etc->phyaddr, 15); ++ if ((estatus != 0xffff) && (estatus & EST_1000TFULL)) { ++ /* read 1000BASE-T control and status registers */ ++ adv2 = (*etc->chops->phyrd)(etc->ch, etc->phyaddr, 9); ++ status2 = (*etc->chops->phyrd)(etc->ch, etc->phyaddr, 10); ++ } ++ ++ /* update current speed and duplex */ ++ if ((adv2 & ADV_1000FULL) && (status2 & LPA_1000FULL)) { ++ etc->speed = 1000; ++ etc->duplex = 1; ++ } else if ((adv2 & ADV_1000HALF) && (status2 & LPA_1000HALF)) { ++ etc->speed = 1000; ++ etc->duplex = 0; ++ } else if ((adv & ADV_100FULL) && (lpa & LPA_100FULL)) { ++ etc->speed = 100; ++ etc->duplex = 1; ++ } else if ((adv & ADV_100HALF) && (lpa & LPA_100HALF)) { ++ etc->speed = 100; ++ etc->duplex = 0; ++ } else if ((adv & ADV_10FULL) && (lpa & LPA_10FULL)) { ++ etc->speed = 10; ++ etc->duplex = 1; ++ } else { ++ etc->speed = 10; ++ etc->duplex = 0; ++ } ++ } ++ ++ /* monitor link state */ ++ if (!etc->linkstate && (status & STAT_LINK)) { ++ etc->linkstate = TRUE; ++ if (etc->pm_modechange) { ++ etc->pm_modechange = FALSE; ++ } else { ++ et_link_up(etc->et); ++#ifdef CONFIG_SERDES_ASYMMETRIC_MODE ++ (*etc->chops->forcespddpx)(etc->ch); ++#endif /* CONFIG_SERDES_ASYMMETRIC_MODE */ ++ } ++ } else if (etc->linkstate && !(status & STAT_LINK)) { ++ etc->linkstate = FALSE; ++ if (!etc->pm_modechange) { ++ et_link_down(etc->et); ++ } ++ } ++ ++ /* keep emac txcontrol duplex bit consistent with current phy duplex */ ++ (*etc->chops->duplexupd)(etc->ch); ++ ++ /* check for remote fault error */ ++ if (status & STAT_REMFAULT) { ++ ET_ERROR(("et%d: remote fault\n", etc->unit)); ++ } ++ ++ /* check for jabber error */ ++ if (status & STAT_JAB) { ++ ET_ERROR(("et%d: jabber\n", etc->unit)); ++ } ++ ++ /* ++ * Read chip mib counters occationally before the 16bit ones can wrap. ++ * We don't use the high-rate mib counters. ++ */ ++ if ((etc->now % 30) == 0) { ++ (*etc->chops->statsupd)(etc->ch); ++ } ++} ++ ++static void ++etc_loopback(etc_info_t *etc, int on) ++{ ++ ET_TRACE(("et%d: etc_loopback: %d\n", etc->unit, on)); ++ ++ etc->loopbk = (bool) on; ++ et_init(etc->et, ET_INIT_INTRON); ++} ++ ++void ++etc_promisc(etc_info_t *etc, uint on) ++{ ++ ET_TRACE(("et%d: etc_promisc: %d\n", etc->unit, on)); ++ ++ etc->promisc = (bool) on; ++ et_init(etc->et, ET_INIT_INTRON); ++} ++ ++void ++etc_qos(etc_info_t *etc, uint on) ++{ ++ ET_TRACE(("et%d: etc_qos: %d\n", etc->unit, on)); ++ ++ etc->qos = (bool) on; ++ et_init(etc->et, ET_INIT_INTRON); ++} ++ ++void ++etc_dump(etc_info_t *etc, struct bcmstrbuf *b) ++{ ++ etc_dumpetc(etc, b); ++ (*etc->chops->dump)(etc->ch, b); ++} ++ ++static void ++etc_dumpetc(etc_info_t *etc, struct bcmstrbuf *b) ++{ ++ char perm[32], cur[32]; ++ uint i; ++ ++ bcm_bprintf(b, "etc 0x%x et 0x%x unit %d msglevel %d speed/duplex %d%s\n", ++ (ulong)etc, (ulong)etc->et, etc->unit, et_msg_level, ++ etc->speed, (etc->duplex ? "full": "half")); ++ bcm_bprintf(b, "up %d promisc %d loopbk %d forcespeed %d advertise 0x%x " ++ "advertise2 0x%x needautoneg %d\n", ++ etc->up, etc->promisc, etc->loopbk, etc->forcespeed, ++ etc->advertise, etc->advertise2, etc->needautoneg); ++ bcm_bprintf(b, "piomode %d pioactive 0x%x nmulticast %d allmulti %d qos %d\n", ++ etc->piomode, (ulong)etc->pioactive, etc->nmulticast, etc->allmulti, etc->qos); ++ bcm_bprintf(b, "vendor 0x%x device 0x%x rev %d coreunit %d phyaddr %d mdcport %d\n", ++ etc->vendorid, etc->deviceid, etc->chiprev, ++ etc->coreunit, etc->phyaddr, etc->mdcport); ++ ++ bcm_bprintf(b, "perm_etheraddr %s cur_etheraddr %s\n", ++ bcm_ether_ntoa(&etc->perm_etheraddr, perm), ++ bcm_ether_ntoa(&etc->cur_etheraddr, cur)); ++ ++ if (etc->nmulticast) { ++ bcm_bprintf(b, "multicast: "); ++ for (i = 0; i < etc->nmulticast; i++) { ++ bcm_bprintf(b, "%s ", bcm_ether_ntoa(&etc->multicast[i], cur)); ++ } ++ bcm_bprintf(b, "\n"); ++ } ++ ++ bcm_bprintf(b, "linkstate %d\n", etc->linkstate); ++ bcm_bprintf(b, "\n"); ++ ++ /* refresh stat counters */ ++ (*etc->chops->statsupd)(etc->ch); ++ ++ /* summary stat counter line */ ++ /* use sw frame and byte counters -- hw mib counters wrap too quickly */ ++ bcm_bprintf(b, "txframe %d txbyte %d txerror %d rxframe %d rxbyte %d rxerror %d\n", ++ etc->txframe, etc->txbyte, etc->txerror, ++ etc->rxframe, etc->rxbyte, etc->rxerror); ++ ++ /* transmit & receive stat counters */ ++ /* hardware mib pkt and octet counters wrap too quickly to be useful */ ++ (*etc->chops->dumpmib)(etc->ch, b, FALSE); ++ ++ bcm_bprintf(b, "txnobuf %d reset %d dmade %d dmada %d dmape %d\n", ++ etc->txnobuf, etc->reset, etc->dmade, etc->dmada, etc->dmape); ++ ++ /* hardware mib pkt and octet counters wrap too quickly to be useful */ ++ bcm_bprintf(b, "rxnobuf %d rxdmauflo %d rxoflo %d rxbadlen %d " ++ "rxgiants %d rxoflodiscards %d\n", ++ etc->rxnobuf, etc->rxdmauflo, etc->rxoflo, etc->rxbadlen, ++ etc->rxgiants, etc->rxoflodiscards); ++ ++ bcm_bprintf(b, "chained %d chainedsz1 %d unchained %d maxchainsz %d currchainsz %d\n", ++ etc->chained, etc->chainedsz1, etc->unchained, etc->maxchainsz, ++ etc->currchainsz); ++ ++ bcm_bprintf(b, "\n"); ++} ++ ++uint ++etc_totlen(etc_info_t *etc, void *p) ++{ ++ uint total; ++ ++ total = 0; ++ for (; p; p = PKTNEXT(etc->osh, p)) { ++ total += PKTLEN(etc->osh, p); ++ } ++ return (total); ++} ++ ++#ifdef BCMDBG ++void ++etc_prhdr(char *msg, struct ether_header *eh, uint len, int unit) ++{ ++ char da[32], sa[32]; ++ ++ if (msg && (msg[0] != '\0')) { ++ printf("et%d: %s: ", unit, msg); ++ } else { ++ printf("et%d: ", unit); ++ } ++ ++ printf("dst %s src %s type 0x%04X len %d\n", ++ bcm_ether_ntoa((struct ether_addr *)eh->ether_dhost, da), ++ bcm_ether_ntoa((struct ether_addr *)eh->ether_shost, sa), ++ ntoh16(eh->ether_type), ++ len); ++} ++void ++etc_prhex(char *msg, uchar *buf, uint nbytes, int unit) ++{ ++ if (msg && (msg[0] != '\0')) { ++ printf("et%d: %s:\n", unit, msg); ++ } else { ++ printf("et%d:\n", unit); ++ } ++ ++ prhex(NULL, buf, nbytes); ++} ++#endif /* BCMDBG */ ++ ++int ++etc_gmac_speed(int gmac) ++{ ++ char name[16], *speed; ++ sprintf(name, "et%dspeed", gmac); ++ ++ speed = nvram_get(name); ++ if (speed == NULL) { ++ printf("%s default GMAC%d speed: auto\n", __FUNCTION__, gmac); ++ return ET_AUTO; ++ } ++ ++ if (!strcmp(speed, "2500")) { ++ printf("%s specifing GMAC%d speed: 2500\n", __FUNCTION__, gmac); ++ return ET_2500FULL; ++ } else if (!strcmp(speed, "1000")) { ++ printf("%s specifing GMAC%d speed: 1000\n", __FUNCTION__, gmac); ++ return ET_1000FULL; ++ } else if (!strcmp(speed, "100")) { ++ printf("%s specifing GMAC%d speed: 100\n", __FUNCTION__, gmac); ++ return ET_100FULL; ++ } else if (!strcmp(speed, "10")) { ++ printf("%s specifing GMAC%d speed: 10\n", __FUNCTION__, gmac); ++ return ET_10FULL; ++ } ++ ++ printf("%s default GMAC%d speed: auto\n", __FUNCTION__, gmac); ++ return ET_AUTO; ++} +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/et/sys/etc.h b/drivers/net/ethernet/broadcom/gmac/src/et/sys/etc.h +--- a/drivers/net/ethernet/broadcom/gmac/src/et/sys/etc.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/et/sys/etc.h 2017-11-09 17:53:43.902294000 +0800 +@@ -0,0 +1,295 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ * ++ * Common [OS-independent] header file for ++ * Broadcom BCM47XX 10/100Mbps Ethernet Device Driver ++ * ++ * $Id: etc.h 327582 2012-04-14 05:02:37Z kenlo $ ++ */ ++ ++#ifndef _ETC_H_ ++#define _ETC_H_ ++ ++#include ++ ++#define MAXMULTILIST 32 ++ ++#ifndef ch_t ++#define ch_t void ++#endif ++ ++#define NUMTXQ 1 ++ ++ ++#define TXREC_THR 8 ++ ++#if defined(__ECOS) ++#define IOCBUFSZ 4096 ++#elif defined(__linux__) ++#define IOCBUFSZ 16384 ++#else ++#define IOCBUFSZ 4096 ++#endif ++ ++struct etc_info; /* forward declaration */ ++struct bcmstrbuf; /* forward declaration */ ++ ++/* each chip type supports a set of chip-type-specific ops */ ++struct chops { ++ bool (*id)(uint vendor, uint device); /* return true if match */ ++ void *(*attach)(struct etc_info *etc, void *dev, void *regs); ++ void (*detach)(ch_t *ch); /* free chip private state */ ++ void (*reset)(ch_t *ch); /* chip reset */ ++ void (*init)(ch_t *ch, uint options); /* chip init */ ++ bool (*tx)(ch_t *ch, void *p); /* transmit frame */ ++ void *(*rx)(ch_t *ch); /* receive frame */ ++ void (*rxfill)(ch_t *ch); /* post dma rx buffers */ ++ int (*getintrevents)(ch_t *ch, bool in_isr); /* return intr events */ ++ bool (*errors)(ch_t *ch); /* handle chip errors */ ++ void (*intrson)(ch_t *ch); /* enable chip interrupts */ ++ void (*intrsoff)(ch_t *ch); /* disable chip interrupts */ ++ void (*txreclaim)(ch_t *ch, bool all); /* reclaim transmit resources */ ++ void (*rxreclaim)(ch_t *ch); /* reclaim receive resources */ ++ void (*statsupd)(ch_t *ch); /* update sw stat counters */ ++ void (*dumpmib)(ch_t *ch, struct bcmstrbuf *, bool clear); /* get sw mib counters */ ++ void (*enablepme)(ch_t *ch); /* enable PME */ ++ void (*disablepme)(ch_t *ch); /* disable PME */ ++ void (*phyreset)(ch_t *ch); /* reset phy */ ++ uint16 (*phyrd)(ch_t *ch, uint phyaddr, uint reg); /* read phy register */ ++ void (*phywr)(ch_t *ch, uint phyaddr, uint reg, uint16 val); /* write phy register */ ++ void (*dump)(ch_t *ch, struct bcmstrbuf *b); /* debugging output */ ++ void (*longname)(ch_t *ch, char *buf, uint bufsize); /* return descriptive name */ ++ void (*duplexupd)(ch_t *ch); /* keep mac duplex consistent */ ++#if defined(CONFIG_SERDES_ASYMMETRIC_MODE) ++ void (*forcespddpx)(ch_t *ch); /* force the speed and duplex */ ++#endif /* (defined(CONFIG_SERDES_ASYMMETRIC_MODE)) */ ++ void (*phyenable)(ch_t *ch, uint eth_num, uint phyaddr, int enable); /* enable phy */ ++}; ++ ++/* ++ * "Common" os-independent software state structure. ++ */ ++typedef struct etc_info { ++ void *et; /* pointer to os-specific private state */ ++ uint unit; /* device instance number */ ++ void *osh; /* pointer to os handler */ ++ bool pktc; /* packet chaining enabled or not */ ++ int pktcbnd; /* max # of packets to chain */ ++ void *mib; /* pointer to s/w maintained mib counters */ ++ bool up; /* interface up and running */ ++ bool promisc; /* promiscuous destination address */ ++ bool qos; /* QoS priority determination on rx */ ++ bool loopbk; /* loopback override mode */ ++ ++ int forcespeed; /* disable autonegotiation and force speed/duplex */ ++ uint advertise; /* control speed/duplex advertised caps */ ++ uint advertise2; /* control gige speed/duplex advertised caps */ ++ bool needautoneg; /* request restart autonegotiation */ ++ int speed; /* current speed: 10, 100 */ ++ int duplex; /* current duplex: 0=half, 1=full */ ++ ++ bool piomode; /* enable programmed io (!dma) */ ++ void *pioactive; /* points to pio packet being transmitted */ ++ volatile uint *txavail[NUMTXQ]; /* dma: # tx descriptors available */ ++ ++ uint16 vendorid; /* pci function vendor id */ ++ uint16 deviceid; /* pci function device id */ ++ uint chip; /* chip number */ ++ uint chiprev; /* chip revision */ ++ uint coreid; /* core id */ ++ uint corerev; /* core revision */ ++ ++ bool nicmode; /* is this core using its own pci i/f */ ++ ++ struct chops *chops; /* pointer to chip-specific opsvec */ ++ void *ch; /* pointer to chip-specific state */ ++ void *robo; /* optional robo private data */ ++ ++ uint txq_state; /* tx queues state bits */ ++ uint coreunit; /* sb chips: chip enet instance # */ ++ uint phyaddr; /* mdio 5-bit phy address for external phy */ ++ uint int_phyaddr; /* mdio 5-bit phy address for internal serdes*/ ++ uint mdcport; /* sb chips: which mii to use (enet core #) to access phy */ ++ ++ struct ether_addr cur_etheraddr; /* our local ethernet address */ ++ struct ether_addr perm_etheraddr; /* original sprom local ethernet address */ ++ ++ struct ether_addr multicast[MAXMULTILIST]; ++ uint nmulticast; ++ bool allmulti; /* enable all multicasts */ ++ ++ bool linkstate; /* link integrity state */ ++ bool pm_modechange; /* true if mode change is to due pm */ ++ ++ uint32 now; /* elapsed seconds */ ++ ++ uint32 boardflags; /* board flags */ ++ uint32 txrec_thresh; /* # of tx frames after which reclaim is done */ ++ uint32 switch_mode; /* switch mode */ ++ ++ uint32 mdio_init_time; /* # of seconds to wait before release mdio bus */ ++ ++#ifdef GMAC_RATE_LIMITING ++ /* rate limiting */ ++ bool rl_enabled; /* enable rate limiting logic */ ++ struct timer_list rl_timer; /* one second ratelimiting timer */ ++ bool rl_set; /* indicate the timer is set or not */ ++ uint32 rl_stopping_all_packets; ++ uint32 rl_stopping_broadcasts; ++ uint32 rl_dropped_all_packets; ++ uint32 rl_dropped_bc_packets; ++ uint32 rl_dropped_packets; ++ uint32 rl_prior_jiffies; ++ uint32 rx_bc_frame_cnt; ++#endif /* GMAC_RATE_LIMITING */ ++ ++ /* sw-maintained stat counters */ ++ uint32 txframes[NUMTXQ]; /* transmitted frames on each tx fifo */ ++ uint32 txframe; /* transmitted frames */ ++ uint32 txbyte; /* transmitted bytes */ ++ uint32 rxframe; /* received frames */ ++ uint32 rxbyte; /* received bytes */ ++ uint32 txerror; /* total tx errors */ ++ uint32 txnobuf; /* tx out-of-buffer errors */ ++ uint32 rxerror; /* total rx errors */ ++ uint32 rxgiants; /* total rx giant frames */ ++ uint32 rxnobuf; /* rx out-of-buffer errors */ ++ uint32 reset; /* reset count */ ++ uint32 dmade; /* pci descriptor errors */ ++ uint32 dmada; /* pci data errors */ ++ uint32 dmape; /* descriptor protocol error */ ++ uint32 rxdmauflo; /* receive descriptor underflow */ ++ uint32 rxoflo; /* receive fifo overflow */ ++ uint32 txuflo; /* transmit fifo underflow */ ++ uint32 rxoflodiscards; /* frames discarded during rx fifo overflow */ ++ uint32 rxbadlen; /* 802.3 len field != read length */ ++ uint32 chained; /* number of frames chained */ ++ uint32 chainedsz1; /* number of chain size 1 frames */ ++ uint32 unchained; /* number of frames not chained */ ++ uint32 maxchainsz; /* max chain size so far */ ++ uint32 currchainsz; /* current chain size */ ++ /* my counters */ ++ uint32 txfrm; /* tx frames */ ++ uint32 txfrmdropped; /* tx dropped frames */ ++ uint32 txqlen; ++ uint32 txqstop; ++ uint32 txdmafull; ++ uint32 txmaxlen; ++ uint32 txsgpkt; ++ uint32 rxquota; ++ uint32 rxdmastopped; ++} etc_info_t; ++ ++/* interrupt event bitvec */ ++#define INTR_TX 0x1 ++#define INTR_RX 0x2 ++#define INTR_ERROR 0x4 ++#define INTR_TO 0x8 ++#define INTR_NEW 0x10 ++ ++/* forcespeed values */ ++#define ET_AUTO -1 ++#define ET_10HALF 0 ++#define ET_10FULL 1 ++#define ET_100HALF 2 ++#define ET_100FULL 3 ++#define ET_1000HALF 4 ++#define ET_1000FULL 5 ++#define ET_2500FULL 6 /* 2.5Gigabit */ ++ ++/* init options */ ++#define ET_INIT_FULL 0x1 ++#define ET_INIT_INTRON 0x2 ++ ++/* Specific init options for et_init */ ++#define ET_INIT_DEF_OPTIONS (ET_INIT_FULL | ET_INIT_INTRON) ++#define ET_INIT_INTROFF (ET_INIT_FULL) ++#define ET_INIT_PARTIAL (0) ++ ++/* macro to safely clear the UP flag */ ++#define ET_FLAG_DOWN(x) (*(x)->chops->intrsoff)((x)->ch); \ ++ (x)->up = FALSE; ++ ++/* ++ * Least-common denominator rxbuf start-of-data offset: ++ * Must be >= size of largest rxhdr ++ * Must be 2-mod-4 aligned so IP is 0-mod-4 ++ */ ++#define HWRXOFF 30 ++ ++#define TC_BK 0 /* background traffic class */ ++#define TC_BE 1 /* best effort traffic class */ ++#define TC_CL 2 /* controlled load traffic class */ ++#define TC_VO 3 /* voice traffic class */ ++#define TC_NONE -1 /* traffic class none */ ++ ++#define RX_Q0 0 /* receive DMA queue */ ++#define NUMRXQ 1 /* gmac has one rx queue */ ++ ++#define TX_Q0 TC_BK /* DMA txq 0 */ ++#define TX_Q1 TC_BE /* DMA txq 1 */ ++#define TX_Q2 TC_CL /* DMA txq 2 */ ++#define TX_Q3 TC_VO /* DMA txq 3 */ ++ ++static inline uint32 ++etc_up2tc(uint32 up) ++{ ++ extern uint32 up2tc[]; ++ return (up2tc[up]); ++} ++ ++static inline uint32 ++etc_priq(uint32 txq_state) ++{ ++ extern uint32 priq_selector[]; ++ return (priq_selector[txq_state]); ++} ++ ++/* rx header flags bits */ ++#define RXH_FLAGS(etc, rxh) (((etc)->coreid == GMAC_CORE_ID) ? \ ++ ((((bcmgmacrxh_t *)(rxh))->flags) & htol16(GRXF_CRC | GRXF_OVF | GRXF_OVERSIZE)) : \ ++ ((((bcmenetrxh_t *)(rxh))->flags) & htol16(RXF_NO | RXF_RXER | RXF_CRC | RXF_OV))) ++ ++#define RXH_OVERSIZE(etc, rxh) (((etc)->coreid == GMAC_CORE_ID) ? \ ++ (ltoh16(((bcmgmacrxh_t *)(rxh))->flags) & GRXF_OVERSIZE) : FALSE) ++ ++#define RXH_PT(etc, rxh) (ltoh16(((bcmgmacrxh_t *)(rxh))->flags) & GRXF_PT_MASK) ++ ++#define RXH_CRC(etc, rxh) (((etc)->coreid == GMAC_CORE_ID) ? \ ++ (ltoh16(((bcmgmacrxh_t *)(rxh))->flags) & GRXF_CRC) : \ ++ (ltoh16(((bcmenetrxh_t *)(rxh))->flags) & RXF_CRC)) ++ ++#define RXH_OVF(etc, rxh) (((etc)->coreid == GMAC_CORE_ID) ? \ ++ (ltoh16(((bcmgmacrxh_t *)(rxh))->flags) & GRXF_OVF) : \ ++ (ltoh16(((bcmenetrxh_t *)(rxh))->flags) & RXF_OV)) ++ ++#define RXH_RXER(etc, rxh) (((etc)->coreid == GMAC_CORE_ID) ? \ ++ FALSE : (ltoh16(((bcmenetrxh_t *)(rxh))->flags) & RXF_RXER)) ++ ++#define RXH_NO(etc, rxh) (((etc)->coreid == GMAC_CORE_ID) ? \ ++ FALSE : (ltoh16(((bcmenetrxh_t *)(rxh))->flags) & RXF_NO)) ++ ++/* Used for fa+ error determination */ ++#define RXH_CTFERROR(etc, rxh) (((etc)->coreid == GMAC_CORE_ID) ? \ ++ (ltoh16(((bcmenetrxh_t *)(rxh))->flags) & (GRXF_CTFERR | GRXF_CRC | GRXF_OVF)) : FALSE) ++ ++#define ET_GMAC(etc) ((etc)->coreid == GMAC_CORE_ID) ++ ++/* exported prototypes */ ++extern struct chops *etc_chipmatch(uint vendor, uint device); ++extern void *etc_attach(void *et, uint vendor, uint device, uint unit, void *dev, void *regsva); ++extern void etc_detach(etc_info_t *etc); ++extern void etc_reset(etc_info_t *etc); ++extern void etc_init(etc_info_t *etc, uint options); ++extern void etc_up(etc_info_t *etc); ++extern uint etc_down(etc_info_t *etc, int reset); ++extern int etc_ioctl(etc_info_t *etc, int cmd, void *arg); ++extern int etc_iovar(etc_info_t *etc, uint cmd, uint set, void *arg); ++extern void etc_promisc(etc_info_t *etc, uint on); ++extern void etc_qos(etc_info_t *etc, uint on); ++extern void etc_dump(etc_info_t *etc, struct bcmstrbuf *b); ++extern void etc_watchdog(etc_info_t *etc); ++extern uint etc_totlen(etc_info_t *etc, void *p); ++extern void etc_robomib(etc_info_t *etc); ++ ++#endif /* _ETC_H_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/et/sys/etcgmac.c b/drivers/net/ethernet/broadcom/gmac/src/et/sys/etcgmac.c +--- a/drivers/net/ethernet/broadcom/gmac/src/et/sys/etcgmac.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/et/sys/etcgmac.c 2017-11-09 17:53:43.904292000 +0800 +@@ -0,0 +1,2593 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ * ++ * Broadcom Gigabit Ethernet MAC (Unimac) core. ++ * This file implements the chip-specific routines for the GMAC core. ++ * ++ * $Id: etcgmac.c 327582 2012-04-14 05:02:37Z kenlo $ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include /* for et_phyxx() routines */ ++#include ++#include ++#include ++#include "bcmiproc_phy.h" ++ ++#define ENABLE_MIB_REG_DUMP ++ ++/* MDIO address definitation */ ++#if defined(CONFIG_MACH_HR3) ++#if defined(CONFIG_MACH_WH2) ++#define GMAC_EXT_PHY_ADDR 0x18 ++#define GMAC_INT_PHY_ADDR 0x14 ++#else ++#define GMAC_EXT_PHY_ADDR 0x18 ++#define GMAC_INT_PHY_ADDR 0xFF ++#endif ++#elif defined(CONFIG_MACH_GH) ++#define GMAC_EXT_PHY_ADDR 0x18 ++#define GMAC_INT_PHY_ADDR 0xFF ++#elif defined(CONFIG_MACH_GH2) ++#define GMAC_EXT_PHY_ADDR 0x10 ++#define GMAC_INT_PHY_ADDR 0x19 ++#else ++#define GMAC_EXT_PHY_ADDR 0x01 ++#define GMAC_INT_PHY_ADDR 0x01 ++#endif ++ ++ ++extern void __iomem *get_iproc_wrap_ctrl_base(void); ++extern void __iomem *get_iproc_idm_base(int index); ++#if defined (CONFIG_MACH_KT2) ++#define IPROC_WRAP_MISC_CONTROL_OFFSET 0x24 ++#elif (defined (CONFIG_MACH_HX4) || defined (CONFIG_MACH_HR2)) ++#define IPROC_WRAP_MISC_CONTROL_OFFSET 0x3C ++#else ++#define IPROC_WRAP_MISC_CONTROL_OFFSET 0x40 ++#endif ++ ++static const u32 idm_ioctl_offset[] = { ++ 0x10408, ++#if defined (CONFIG_MACH_HX4) || defined (CONFIG_MACH_KT2) ++ 0x11408, ++#elif defined (CONFIG_MACH_SB2) || defined(CONFIG_MACH_GH2) ++ 0x1f408, ++#endif ++}; ++#define AMAC_IDM_IO_CONTROL_DIRECT__CLK_250_SEL 6 ++#define AMAC_IDM_IO_CONTROL_DIRECT__DIRECT_GMII_MODE 5 ++#define AMAC_IDM_IO_CONTROL_DIRECT__DEST_SYNC_MODE_EN 3 ++ ++#if defined(CONFIG_MACH_HX4) ++#define IPROC_WRAP_MISC_CONTROL__QUAD_SERDES_MDIO_SEL 3 ++#define IPROC_WRAP_MISC_CONTROL__QUAD_SERDES_CTRL_SEL 2 ++#define IPROC_WRAP_MISC_CONTROL__IPROC_MDIO_SEL 4 ++#endif /* defined(CONFIG_MACH_HX4) */ ++ ++#if defined(CONFIG_MACH_KT2) ++#define IPROC_WRAP_MISC_CONTROL__UNICORE_SERDES_CTRL_SEL 1 ++#define IPROC_WRAP_MISC_CONTROL__UNICORE_SERDES_MDIO_SEL 2 ++#define IPROC_WRAP_MISC_CONTROL__IPROC_MDIO_SEL 3 ++#endif /* defined(CONFIG_MACH_KT2) */ ++ ++#if defined(CONFIG_MACH_SB2) || defined(CONFIG_MACH_WH2) ++#define IPROC_WRAP_MISC_CONTROL__IPROC_MDIO_SEL 1 ++#endif /* defined(CONFIG_MACH_SB2) */ ++ ++ ++#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || defined(CONFIG_MACH_SB2)) ++#include "bcmiproc_serdes.h" ++#include "bcmiproc_phy5461s.h" ++#elif defined(CONFIG_MACH_GH2) ++#include "sgmiiplus2_serdes.h" ++#include "phy542xx.h" ++#elif defined(CONFIG_MACH_HR3) ++#if defined(CONFIG_MACH_WH2) ++#include "../../../mdio/iproc_mdio.h" ++#include "sgmiiplus2_serdes.h" ++#include "bcmiproc_egphy28.h" ++#include ++#define IPROC_CMICD_COMPATIBLE "brcm,iproc-cmicd" ++#define CMIC_SBUS_RING_MAP_0_7(base) (base + 0x10098) ++#define CMIC_SBUS_RING_MAP_8_15(base) (base + 0x1009C) ++#define CMIC_SBUS_RING_MAP_16_23(base) (base + 0x100A0) ++#define CMIC_SBUS_RING_MAP_24_31(base) (base + 0x100A4) ++extern u32 cmicd_schan_read(void __iomem *base, u32 ctrl, u32 addr); ++extern u32 cmicd_schan_write(void __iomem *base, u32 ctrl, u32 addr, u32 val); ++extern int egphy28_init(void __iomem *base, u32 phy_addr); ++#else ++#include "bcmiproc_phy5481.h" ++#endif ++#elif defined(CONFIG_MACH_HR2) ++#include "bcmiproc_phy5221.h" ++#elif defined(CONFIG_MACH_GH) ++#include "bcmiproc_phy5481.h" ++#endif ++ ++ ++#if !defined(CONFIG_MACH_HR2) ++/* BCM5221 on HR2 board does not support this feature */ ++#define CONFIG_FORCED_MODE_AUTO_MDIX 1 ++#endif ++ ++struct bcmgmac; /* forward declaration */ ++#define ch_t struct bcmgmac ++#include ++ ++extern int nvram_env_gmac_name(int gmac, char *name); ++ ++/* private chip state */ ++struct bcmgmac { ++ void *et; /* pointer to et private state */ ++ etc_info_t *etc; /* pointer to etc public state */ ++ ++ gmac_commonregs_t *regscomm; /* pointer to GMAC COMMON registers */ ++ gmacregs_t *regs; /* pointer to chip registers */ ++ osl_t *osh; /* os handle */ ++ ++ void *etphy; /* pointer to et for shared mdc/mdio contortion */ ++ ++ uint32 intstatus; /* saved interrupt condition bits */ ++ uint32 intmask; /* current software interrupt mask */ ++ uint32 def_intmask;/* default interrupt mask */ ++ ++ hnddma_t *di[NUMTXQ];/* dma engine software state */ ++ ++ bool mibgood; /* true once mib registers have been cleared */ ++ gmacmib_t mib; /* mib statistic counters */ ++ si_t *sih; /* si utils handle */ ++ ++ char *vars; /* sprom name=value */ ++ uint vars_size; ++ ++ void *adm; /* optional admtek private data */ ++ mcfilter_t mf; /* multicast filter */ ++}; ++ ++/* local prototypes */ ++static bool chipid(uint vendor, uint device); ++static void *chipattach(etc_info_t *etc, void *osh, void *regsva); ++static void chipdetach(ch_t *ch); ++static void chipreset(ch_t *ch); ++static void chipinit(ch_t *ch, uint options); ++static bool chiptx(ch_t *ch, void *p); ++static void *chiprx(ch_t *ch); ++static void chiprxfill(ch_t *ch); ++static int chipgetintrevents(ch_t *ch, bool in_isr); ++static bool chiperrors(ch_t *ch); ++static void chipintrson(ch_t *ch); ++static void chipintrsoff(ch_t *ch); ++static void chiptxreclaim(ch_t *ch, bool all); ++static void chiprxreclaim(ch_t *ch); ++static void chipstatsupd(ch_t *ch); ++static void chipdumpmib(ch_t *ch, struct bcmstrbuf *b, bool clear); ++static void chipenablepme(ch_t *ch); ++static void chipdisablepme(ch_t *ch); ++static void chipphyreset(ch_t *ch); ++static uint16 chipphyrd(ch_t *ch, uint phyaddr, uint reg); ++static void chipphywr(ch_t *ch, uint phyaddr, uint reg, uint16 val); ++static void chipdump(ch_t *ch, struct bcmstrbuf *b); ++static void chiplongname(ch_t *ch, char *buf, uint bufsize); ++static void chipduplexupd(ch_t *ch); ++#ifdef CONFIG_SERDES_ASYMMETRIC_MODE ++static void chipforcespddpx(ch_t *ch); ++#endif /* CONFIG_SERDES_ASYMMETRIC_MODE */ ++ ++static void chipphyinit(ch_t *ch); ++static void chipphyor(ch_t *ch, uint phyaddr, uint reg, uint16 v); ++static void chipphyforce(ch_t *ch, uint phyaddr); ++static void chipphyadvertise(ch_t *ch, uint phyaddr); ++static void chipphyenable(ch_t *ch, uint eth_num, uint phyaddr, int enable); ++static void chipdumpregs(ch_t *ch, gmacregs_t *regs, struct bcmstrbuf *b); ++static void gmac_mf_cleanup(ch_t *ch); ++static int gmac_speed(ch_t *ch, uint32 speed); ++#if defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || \ ++ defined(CONFIG_MACH_SB2) || defined(CONFIG_MACH_GH2) || defined(CONFIG_MACH_WH2) ++static void gmac_serdes_init(ch_t *ch); ++#endif ++static void gmac_miiconfig(ch_t *ch); ++ ++struct chops bcmgmac_et_chops = { ++ chipid, ++ chipattach, ++ chipdetach, ++ chipreset, ++ chipinit, ++ chiptx, ++ chiprx, ++ chiprxfill, ++ chipgetintrevents, ++ chiperrors, ++ chipintrson, ++ chipintrsoff, ++ chiptxreclaim, ++ chiprxreclaim, ++ chipstatsupd, ++ chipdumpmib, ++ chipenablepme, ++ chipdisablepme, ++ chipphyreset, ++ chipphyrd, ++ chipphywr, ++ chipdump, ++ chiplongname, ++ chipduplexupd, ++#ifdef CONFIG_SERDES_ASYMMETRIC_MODE ++ chipforcespddpx, ++#endif /* CONFIG_SERDES_ASYMMETRIC_MODE */ ++ chipphyenable ++}; ++ ++static uint devices[] = { ++ BCM56150_CHIP_ID, ++ BCM56340_CHIP_ID, ++ BCM56450_CHIP_ID, ++ BCM53400_CHIP_ID, ++ BCM56260_CHIP_ID, ++ BCM56160_CHIP_ID, ++ BCM56170_CHIP_ID, ++ BCM53540_CHIP_ID, ++ 0x0000 ++}; ++ ++ ++#if defined(CONFIG_MACH_WH2) ++static uint32 select = 0x06; ++ ++static void ++cmid_schan_modify(void __iomem *base, u32 ctrl, u32 addr, u32 val, u32 mask) ++{ ++ u32 ori_val; ++ ++ ori_val = cmicd_schan_read(base, ctrl, addr); ++ ori_val &= ~mask; ++ ori_val |= (val & mask); ++ cmicd_schan_write(base, ctrl + 0x08000000, addr, ori_val); ++} ++ ++static void power_on_serdesphy(ch_t *ch) ++{ ++ void __iomem *base; ++ uint32 val; ++ int i; ++ ++ select = (ioread32(get_iproc_wrap_ctrl_base() + 0xa8)); /* IPROC_WRAP_TOP_STRAP_STATUS_1 */ ++ base = of_iomap(of_find_compatible_node(NULL, NULL, IPROC_CMICD_COMPATIBLE), 0); ++ //* Configure SBUS Ring Map for TOP, block id = 16, ring number = 4 */ ++ writel(0x00000000, CMIC_SBUS_RING_MAP_0_7(base)); ++ writel(0x00430000, CMIC_SBUS_RING_MAP_8_15(base)); ++ writel(0x00005064, CMIC_SBUS_RING_MAP_16_23(base)); ++ writel(0x00000000, CMIC_SBUS_RING_MAP_24_31(base)); ++ ++ if (select & 0x04) /* select Serdes (SGMII Plus2) path */ ++ { ++ printf("AMAC selects SGMII path... \n"); ++ ++ /* Reset TOP_SGMII_CTRL_REG through S-Channel */ ++ /* bit 2 (RSTB_HW) & 3 (IDDQ) & 4 (PWRDWN) = 0 */ ++ cmid_schan_modify(base, 0x2c800200, 0x0207e800, 0x0, 0x0000001c); ++ /* bit 2 (RSTB_HW) & 1 (RSTB_MDIOREGS) & 0 (RSTB_PLL) = 1 */ ++ cmid_schan_modify(base, 0x2c800200, 0x0207e800, 0x00000007, 0x00000007); ++ ++ /* Hardware reset 4th lane. PHY addr = 0x17, Reg addr = 0x0000, bit 15 = 1 */ ++ val = chipphyrd(ch, GMAC_INT_PHY_ADDR, 0x0000); ++ val |= (1 << 15); ++ chipphywr(ch, GMAC_INT_PHY_ADDR, 0x0000, val); ++ ++ /* Power down other 3 lanes. PHY addr = (0x14, 0x15, 0x16) */ ++ for (i = 0; i < 3; ++i) ++ { ++ val = chipphyrd(ch, GMAC_INT_PHY_ADDR + i, 0x0); ++ val |= (1 << 11); ++ chipphywr(ch, GMAC_INT_PHY_ADDR + i, 0x0, val); ++ } ++ } else /* select EGPHY28 path */ ++ { ++ printf("AMAC selects EGPHY path... \n"); ++ ++ /* TOP_QGPHY_CTRL_0.EXT_PWRDOWN[23:20] = HIGH */ ++ cmid_schan_modify(base, 0x2c800200, 0x02033800, 0x00F00000, 0x00F00000); ++ /* TOP_QGPHY_CTRL_2.GPHY_IDDQ_GLOBAL_PWR[18] = LOW */ ++ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x0, 0x040000); ++ /* TOP_QGPHY_CTRL_2.IDDQ_BIAS[5] = HIGH */ ++ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x20, 0x20); ++ /* TOP_SOFT_RESET_REG.TOP_QGPHY_RST_L[21] = HIGH */ ++ cmid_schan_modify(base, 0x2c800200, 0x02030400, 0x200000, 0x200000); ++ ++ /* TOP_QGPHY_CTRL_2.GPHY_IDDQ_GLOBAL_PWR[18] = HIGH */ ++ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x040000, 0x040000); ++ /* TOP_SOFT_RESET_REG.TOP_QGPHY_RST_L[21] = LOW */ ++ cmid_schan_modify(base, 0x2c800200, 0x02030400, 0x0, 0x200000); ++ /* Reset TOP_SOFT_RESET_REG bit 4 (GXP2_RST) & 5 (GXP0_RST) & 6 (GXP1_RST) = 0 */ ++ cmid_schan_modify(base, 0x2c800200, 0x02030400, 0x0, 0x00000070); ++ ++ mdelay(100); ++ ++ /* Give initial value */ ++ /* TOP_QGPHY_CTRL_0.EXT_PWRDOWN[23:20] = LOW */ ++ cmid_schan_modify(base, 0x2c800200, 0x02033800, 0x0, 0x00F00000); ++ /* TOP_QGPHY_CTRL_2.GPHY_IDDQ_GLOBAL_PWR[18] = HIGH */ ++ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x40000, 0x040000); ++ /* TOP_QGPHY_CTRL_2.IDDQ_BIAS[5] = LOW */ ++ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x0, 0x20); ++ /* TOP_SOFT_RESET_REG.TOP_QGPHY_RST_L[21] = LOW */ ++ cmid_schan_modify(base, 0x2c800200, 0x02030400, 0x0, 0x200000); ++ ++ /* TOP_QGPHY_CTRL_2.GPHY_IDDQ_GLOBAL_PWR[18] = LOW */ ++ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x0, 0x040000); ++ /* TOP_SOFT_RESET_REG.TOP_QGPHY_RST_L[21] = HIGH */ ++ cmid_schan_modify(base, 0x2c800200, 0x02030400, 0x200000, 0x200000); ++ /* Reset TOP_SOFT_RESET_REG bit 4 (GXP2_RST) & 5 (GXP0_RST) & 6 (GXP1_RST) = 1 */ ++ cmid_schan_modify(base, 0x2c800200, 0x02030400, 0x00000070, 0x00000070); ++ } ++} ++#endif ++ ++#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || defined(CONFIG_MACH_SB2)) ++static void *wrapaddr = 0; ++void gmac_set_amac_mdio(int en) ++{ ++ u32 tmp; ++#if defined(CONFIG_MACH_HX4) ++ u32 mdio_sel= IPROC_WRAP_MISC_CONTROL__QUAD_SERDES_MDIO_SEL; ++ u32 ctrl_sel= IPROC_WRAP_MISC_CONTROL__QUAD_SERDES_CTRL_SEL; ++#elif defined(CONFIG_MACH_KT2) ++ u32 mdio_sel= IPROC_WRAP_MISC_CONTROL__UNICORE_SERDES_MDIO_SEL; ++ u32 ctrl_sel= IPROC_WRAP_MISC_CONTROL__UNICORE_SERDES_CTRL_SEL; ++#endif ++ u32 iproc_mdio_sel= IPROC_WRAP_MISC_CONTROL__IPROC_MDIO_SEL; ++ ++ if (en) { ++ /* Get register base address */ ++ wrapaddr = get_iproc_wrap_ctrl_base() + IPROC_WRAP_MISC_CONTROL_OFFSET; ++ } ++ ++ tmp = ioread32(wrapaddr); ++ if (en) { ++#if defined(CONFIG_MACH_SB2) ++ /* set bits IPROC_WRAP_MISC_CONTROL__IPROC_MDIO_SEL ++ so AMAC can access the Serdes and Phy */ ++ tmp |= (1 << iproc_mdio_sel); ++#else ++ /* set bits IPROC_WRAP_MISC_CONTROL__IPROC_MDIO_SEL, ++ IPROC_WRAP_MISC_CONTROL__QUAD_SERDES_MDIO_SEL & ++ IPROC_WRAP_MISC_CONTROL__QUAD_SERDES_CTRL_SEL ++ so AMAC can access the Serdes and Phy */ ++ tmp |= ((1 << mdio_sel) | (1 << ctrl_sel) | (1 << iproc_mdio_sel)); ++#endif ++ } else { ++#if defined(CONFIG_MACH_SB2) ++ /* clear bits IPROC_WRAP_MISC_CONTROL__IPROC_MDIO_SEL ++ so CMIC can access the Serdes and Phy */ ++ tmp &= ~(1 << iproc_mdio_sel); ++#else ++ /* clear bits IPROC_WRAP_MISC_CONTROL__IPROC_MDIO_SEL & ++ IPROC_WRAP_MISC_CONTROL__QUAD_SERDES_MDIO_SEL ++ so CMIC can access the Serdes and Phy */ ++ tmp &= ~((1 << mdio_sel) | (1 << iproc_mdio_sel)); ++#endif ++ } ++ iowrite32(tmp, wrapaddr); ++ ++ if (!en) { ++ wrapaddr=0; ++ } ++} ++ ++int gmac_has_mdio_access(void) ++{ ++ u32 tmp; ++ u32 regmsk = (1 << IPROC_WRAP_MISC_CONTROL__IPROC_MDIO_SEL); ++ ++#if defined(CONFIG_MACH_HX4) ++ regmsk |= ((1 << IPROC_WRAP_MISC_CONTROL__QUAD_SERDES_MDIO_SEL) | ++ (1 << IPROC_WRAP_MISC_CONTROL__QUAD_SERDES_CTRL_SEL)); ++#elif defined(CONFIG_MACH_KT2) ++ regmsk |= ((1 << IPROC_WRAP_MISC_CONTROL__UNICORE_SERDES_MDIO_SEL) | ++ (1 << IPROC_WRAP_MISC_CONTROL__UNICORE_SERDES_CTRL_SEL)); ++#endif ++ ++ if (wrapaddr==0) { ++ /* if no wrapaddr then no access */ ++ return 0; ++ } ++ ++ tmp = ioread32(wrapaddr); ++ tmp &= ~regmsk; ++ if (tmp == regmsk) { ++ return 0; ++ } ++ ++ return 1; ++} ++#endif /* (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || defined(CONFIG_MACH_SB2)) */ ++ ++/* This api will determine if this unit specified is the last interface. */ ++bool gmac_last_interface(int unit) ++{ ++ char name[128]; ++ int idx; ++ ++ /* if interface 2 or greater then must be last */ ++ if (unit >= 2) { ++ return true; ++ } ++ ++ /* Look to see if there is a next interface specified */ ++ for (idx = unit + 1; idx <= 2; idx++) { ++ nvram_env_gmac_name(idx, name); ++ if (getvar(NULL, name) != NULL) { ++ /* there is a next interface */ ++ return false; ++ } ++ } ++ /* no other interfaces */ ++ return true; ++} ++ ++ ++static bool ++chipid(uint vendor, uint device) ++{ ++ int idx; ++ ++ if (vendor != VENDOR_BROADCOM) { ++ ET_ERROR(("%s ERROR: NOT a BROADCOM Vendor ID (0x%x)\n", __FUNCTION__, vendor)); ++ return (FALSE); ++ } ++ ++ for (idx = 0; devices[idx]; idx++) { ++ if (device == devices[idx]) { ++ return (TRUE); ++ } ++ } ++ ++ ET_ERROR(("%s ERROR: UNKNOWN Device ID (0x%x)\n", __FUNCTION__, device)); ++ printk("%s ERROR: UNKNOWN Device ID (0x%x)\n", __FUNCTION__, device); ++ return (FALSE); ++} ++ ++static void * ++chipattach(etc_info_t *etc, void *osh, void *regsva) ++{ ++ ch_t *ch; ++ gmacregs_t *regs; ++ void *amacidmaddr; ++ uint32 idx, tmp; ++ char name[16], *var; ++ uint boardflags, boardtype; ++ uint coreidx; ++ ulong flags; ++ ++ ET_TRACE(("et%d: chipattach: regsva 0x%lx\n", etc->unit, (ulong)regsva)); ++ ++ if ((ch = (ch_t *)MALLOC(osh, sizeof(ch_t))) == NULL) { ++ ET_ERROR(("et%d: chipattach: out of memory, malloced %d bytes\n", etc->unit, MALLOCED(osh))); ++ return (NULL); ++ } ++ bzero((char *)ch, sizeof(ch_t)); ++ ++ ch->etc = etc; ++ ch->et = etc->et; ++ ch->osh = osh; ++ ++ /* store the pointer to the sw mib */ ++ etc->mib = (void *)&ch->mib; ++ ++ /* get si handle */ ++ if ((ch->sih = si_attach(etc->deviceid, ch->osh, regsva, SI_BUS, NULL, &ch->vars, ++ &ch->vars_size)) == NULL) { ++ ET_ERROR(("et%d: chipattach: si_attach error\n", etc->unit)); ++ goto fail; ++ } ++ ++ if ((regs = (gmacregs_t *)si_setcore(ch->sih, GMAC_CORE_ID, etc->unit)) == NULL) { ++ ET_ERROR(("et%d: chipattach: Could not setcore to GMAC\n", etc->unit)); ++ goto fail; ++ } ++ ++ /* 2G_ENABLED: Enable IDM 250MHz for 2G mode */ ++ spin_lock_irqsave((spinlock_t *)&ch->sih->sih_lock, flags); ++ ++ coreidx = si_coreidx(ch->sih); ++ si_core_reset(ch->sih, 0, 0); ++ si_setcoreidx(ch->sih, coreidx); ++ ++ spin_unlock_irqrestore((spinlock_t *)&ch->sih->sih_lock, flags); ++ ++ ch->regs = regs; ++ etc->chip = ch->sih->chip; ++ etc->chiprev = ch->sih->chiprev; ++ etc->coreid = si_coreid(ch->sih); ++ etc->nicmode = !(ch->sih->bustype == SI_BUS); ++ etc->coreunit = si_coreunit(ch->sih); ++ etc->boardflags = getintvar(ch->vars, "boardflags"); ++ ++ boardflags = etc->boardflags; ++ boardtype = ch->sih->boardtype; ++ ++ etc->switch_mode = 0; ++ ++ /* ++ * Too much can go wrong in scanning MDC/MDIO playing "whos my phy?" . ++ * Instead, explicitly require the environment var "etphyaddr=". ++ */ ++ ++ /* get our phyaddr value */ ++ sprintf(name, "et%dphyaddr", etc->coreunit); ++ var = getvar(NULL, name); ++ if (var == NULL) { ++ etc->phyaddr = etc->unit + GMAC_EXT_PHY_ADDR; ++ etc->int_phyaddr = etc->unit + GMAC_INT_PHY_ADDR; ++ } else { ++ etc->phyaddr = bcm_atoi(var) & EPHY_MASK; ++ etc->int_phyaddr = etc->unit + GMAC_INT_PHY_ADDR; ++ } ++ printf("et%d: chipattach: phyaddr(0x%x)\n", etc->unit, etc->phyaddr); ++ ++ /* nvram says no phy is present */ ++ if (etc->phyaddr == EPHY_NONE) { ++ ET_ERROR(("et%d: chipattach: phy not present\n", etc->unit)); ++ goto fail; ++ } ++ ++ /* reset the gmac core */ ++ chipreset(ch); ++ ++#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || defined(CONFIG_MACH_SB2)) ++ /* flip switch so AMAC can access serdes */ ++ if (wrapaddr == 0) { ++ gmac_set_amac_mdio(1); ++ } ++#elif defined(CONFIG_MACH_WH2) ++ /* power on SGMII/EGPHY most before chipphyreset() to read PHY ID */ ++ power_on_serdesphy(ch); ++#endif /* (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || defined(CONFIG_MACH_SB2)) */ ++ ++ /* Get register base address */ ++ amacidmaddr = get_iproc_idm_base(0) + idm_ioctl_offset[etc->unit]; ++ tmp = ioread32(amacidmaddr); ++ tmp &= ~(1 << AMAC_IDM_IO_CONTROL_DIRECT__CLK_250_SEL); ++ tmp |= (1 << AMAC_IDM_IO_CONTROL_DIRECT__DIRECT_GMII_MODE); ++ tmp |= (1 << AMAC_IDM_IO_CONTROL_DIRECT__DEST_SYNC_MODE_EN); ++ iowrite32(tmp, amacidmaddr); ++ ++#if defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || \ ++ defined(CONFIG_MACH_SB2) || defined(CONFIG_MACH_GH2) ++ /* enable serdes */ ++ gmac_serdes_init(ch); ++#elif defined(CONFIG_MACH_WH2) ++ if (select & 0x04) /* select Serdes (SGMII Plus2) path */ ++ gmac_serdes_init(ch); ++#endif ++ ++ /* dma attach */ ++ sprintf(name, "et%d", etc->coreunit); ++ ++ /* allocate dma resources for txqs */ ++ /* TX: TC_BK, RX: RX_Q0 */ ++ ch->di[0] = dma_attach(osh, name, ch->sih, ++ DMAREG(ch, DMA_TX, TX_Q0), ++ DMAREG(ch, DMA_RX, RX_Q0), ++ NTXD, NRXD, RXBUFSZ, -1, NRXBUFPOST, HWRXOFF, ++ &et_msg_level); ++ ++ for (idx = 0; idx < NUMTXQ; idx++) { ++ if (ch->di[idx] == NULL) { ++ ET_ERROR(("et%d: chipattach: dma_attach failed\n", etc->unit)); ++ goto fail; ++ } ++ } ++ ++ for (idx = 0; idx < NUMTXQ; idx++) { ++ if (ch->di[idx] != NULL) { ++ etc->txavail[idx] = (uint *)&ch->di[idx]->txavail; ++ } ++ } ++ ++ /* set default sofware intmask */ ++ sprintf(name, "et%d_no_txint", etc->coreunit); ++ if (getintvar(ch->vars, name)) { ++ /* if no_txint variable is non-zero we disable tx interrupts. ++ * we do the tx buffer reclaim once every few frames. ++ */ ++ ch->def_intmask = (DEF_INTMASK & ~(I_XI0 | I_XI1 | I_XI2 | I_XI3)); ++ etc->txrec_thresh = (((NTXD >> 2) > TXREC_THR) ? TXREC_THR - 1 : 1); ++ } else { ++ ch->def_intmask = DEF_INTMASK; ++ } ++ ++ ch->intmask = ch->def_intmask; ++ ++ /* reset phy: reset it once now */ ++#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) ++ if (ch->etc->unit == 0) { ++ serdes_reset_core(ch->etc->unit, etc->int_phyaddr); ++ } ++#endif ++ ++ chipphyreset(ch); ++#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) ++ if (gmac_last_interface(etc->unit)) { ++ /* ++ * The 4-lane serdes is shared between XLDK and SDK. XLDK has to ++ * initialize the 3rd lane (phy address 3) that is used by SDK. ++ */ ++ serdes_init(etc->unit, 3); ++ serdes_start_pll(etc->unit, 1); ++ } ++#endif ++ ++ if (etc->forcespeed == ET_AUTO) { ++ etc->needautoneg = TRUE; ++ etc->advertise = (ADV_100FULL | ADV_100HALF | ADV_10FULL | ADV_10HALF); ++#if defined(CONFIG_MACH_HR2) ++ etc->advertise2 = 0; ++#else ++ etc->advertise2 = ADV_1000FULL; ++#endif ++ } ++ ++ return ((void *) ch); ++ ++fail: ++ chipdetach(ch); ++ return (NULL); ++} ++ ++static void ++chipdetach(ch_t *ch) ++{ ++ int32 idx; ++ ++ ET_TRACE(("et%d: chipdetach\n", ch->etc->unit)); ++ ++ if (ch == NULL) { ++ return; ++ } ++ ++ /* free dma state */ ++ for (idx = 0; idx < NUMTXQ; idx++) { ++ if (ch->di[idx] != NULL) { ++ dma_detach(ch->di[idx]); ++ ch->di[idx] = NULL; ++ } ++ } ++ ++ /* put the core back into reset */ ++ if (ch->sih) { ++ si_core_disable(ch->sih, 0); ++ } ++ ++ if (ch->etc) { ++ if (ch->etc->mib) { ++ ch->etc->mib = NULL; ++ } ++ } ++ ++ /* free si handle */ ++ if (ch->sih) { ++ si_detach(ch->sih); ++ ch->sih = NULL; ++ } ++ ++ /* free vars */ ++ if (ch->vars) { ++ MFREE(ch->osh, ch->vars, ch->vars_size); ++ } ++ ++ /* free chip private state */ ++ MFREE(ch->osh, ch, sizeof(ch_t)); ++} ++ ++static void ++chiplongname(ch_t *ch, char *buf, uint bufsize) ++{ ++ char *s; ++ ++ switch (ch->etc->deviceid) { ++ case BCM56150_CHIP_ID: ++ s = "Broadcom BCM5615x 10/100 Mbps Ethernet Controller"; ++ break; ++ case BCM56340_CHIP_ID: ++ s = "Broadcom BCM5634x 10/100/1000 Mbps Ethernet Controller"; ++ break; ++ case BCM56450_CHIP_ID: ++ s = "Broadcom BCM5645x 10/100/1000 Mbps Ethernet Controller"; ++ break; ++ case BCM53400_CHIP_ID: ++ s = "Broadcom BCM5340x 10/100/1000 Mbps Ethernet Controller"; ++ break; ++ case BCM56260_CHIP_ID: ++ s = "Broadcom BCM5626x 10/100/1000 Mbps Ethernet Controller"; ++ break; ++ case BCM56160_CHIP_ID: ++ s = "Broadcom BCM5616x 10/100/1000 Mbps Ethernet Controller"; ++ break; ++ case BCM53540_CHIP_ID: ++ s = "Broadcom BCM5354x 10/100/1000 Mbps Ethernet Controller"; ++ break; ++ case BCM56170_CHIP_ID: ++ s = "Broadcom BCM5617x 10/100/1000 Mbps Ethernet Controller"; ++ break; ++ default: ++ s = "Broadcom BCM5301x 10/100/1000 Mbps Ethernet Controller"; ++ break; ++ } ++ ++ strncpy(buf, s, bufsize); ++ buf[bufsize - 1] = '\0'; ++} ++ ++static void ++chipdump(ch_t *ch, struct bcmstrbuf *b) ++{ ++ bcm_bprintf(b, "regs 0x%lx etphy 0x%lx ch->intstatus 0x%x intmask 0x%x\n", ++ (ulong)ch->regs, (ulong)ch->etphy, ch->intstatus, ch->intmask); ++ bcm_bprintf(b, "\n"); ++ ++ /* registers */ ++ chipdumpregs(ch, ch->regs, b); ++ bcm_bprintf(b, "\n"); ++} ++ ++ ++#define PRREG(name) bcm_bprintf(b, #name " 0x%x ", R_REG(ch->osh, ®s->name)) ++#define PRMIBREG(name) bcm_bprintf(b, #name " 0x%x ", R_REG(ch->osh, ®s->mib.name)) ++ ++static void ++chipdumpregs(ch_t *ch, gmacregs_t *regs, struct bcmstrbuf *b) ++{ ++ uint phyaddr; ++ ++ phyaddr = ch->etc->phyaddr; ++ ++ PRREG(devcontrol); PRREG(devstatus); ++ bcm_bprintf(b, "\n"); ++ PRREG(biststatus); ++ bcm_bprintf(b, "\n"); ++ PRREG(intstatus); PRREG(intmask); PRREG(gptimer); ++ bcm_bprintf(b, "\n"); ++ PRREG(intrecvlazy); ++ bcm_bprintf(b, "\n"); ++ PRREG(flowctlthresh); PRREG(wrrthresh); PRREG(gmac_idle_cnt_thresh); ++ bcm_bprintf(b, "\n"); ++ PRREG(phyaccess); PRREG(phycontrol); ++ bcm_bprintf(b, "\n"); ++ ++ PRREG(txqctl); PRREG(rxqctl); ++ bcm_bprintf(b, "\n"); ++ PRREG(gpioselect); PRREG(gpio_output_en); ++ bcm_bprintf(b, "\n"); ++ PRREG(clk_ctl_st); PRREG(pwrctl); ++ bcm_bprintf(b, "\n"); ++ ++ /* unimac registers */ ++ PRREG(hdbkpctl); ++ bcm_bprintf(b, "\n"); ++ PRREG(cmdcfg); ++ bcm_bprintf(b, "\n"); ++ PRREG(macaddrhigh); PRREG(macaddrlow); ++ bcm_bprintf(b, "\n"); ++ PRREG(rxmaxlength); PRREG(pausequanta); PRREG(macmode); ++ bcm_bprintf(b, "\n"); ++ PRREG(outertag); PRREG(innertag); PRREG(txipg); PRREG(pausectl); ++ bcm_bprintf(b, "\n"); ++ PRREG(txflush); PRREG(rxstatus); PRREG(txstatus); ++ bcm_bprintf(b, "\n"); ++#ifdef ENABLE_MIB_REG_DUMP ++ /* mib registers */ ++ PRMIBREG(tx_good_octets); PRMIBREG(tx_good_pkts); PRMIBREG(tx_octets); PRMIBREG(tx_pkts); ++ bcm_bprintf(b, "\n"); ++ PRMIBREG(tx_broadcast_pkts); PRMIBREG(tx_multicast_pkts); ++ bcm_bprintf(b, "\n"); ++ PRMIBREG(tx_jabber_pkts); PRMIBREG(tx_oversize_pkts); PRMIBREG(tx_fragment_pkts); ++ bcm_bprintf(b, "\n"); ++ PRMIBREG(tx_underruns); PRMIBREG(tx_total_cols); PRMIBREG(tx_single_cols); ++ bcm_bprintf(b, "\n"); ++ PRMIBREG(tx_multiple_cols); PRMIBREG(tx_excessive_cols); PRMIBREG(tx_late_cols); ++ bcm_bprintf(b, "\n"); ++ PRMIBREG(tx_defered); PRMIBREG(tx_carrier_lost); PRMIBREG(tx_pause_pkts); ++ bcm_bprintf(b, "\n"); ++ ++ PRMIBREG(rx_good_octets); PRMIBREG(rx_good_pkts); PRMIBREG(rx_octets); PRMIBREG(rx_pkts); ++ bcm_bprintf(b, "\n"); ++ PRMIBREG(rx_broadcast_pkts); PRMIBREG(rx_multicast_pkts); ++ bcm_bprintf(b, "\n"); ++ PRMIBREG(rx_jabber_pkts); ++ PRMIBREG(rx_oversize_pkts); PRMIBREG(rx_fragment_pkts); ++ bcm_bprintf(b, "\n"); ++ PRMIBREG(rx_missed_pkts); PRMIBREG(rx_crc_align_errs); PRMIBREG(rx_undersize); ++ bcm_bprintf(b, "\n"); ++ PRMIBREG(rx_crc_errs); PRMIBREG(rx_align_errs); PRMIBREG(rx_symbol_errs); ++ bcm_bprintf(b, "\n"); ++ PRMIBREG(rx_pause_pkts); PRMIBREG(rx_nonpause_pkts); ++#endif /* ENABLE_MIB_REG_DUMP */ ++ bcm_bprintf(b, "\n"); ++ if (phyaddr != EPHY_NOREG) { ++ /* print a few interesting phy registers */ ++ bcm_bprintf(b, "phy0 0x%x phy1 0x%x phy2 0x%x phy3 0x%x\n", ++ chipphyrd(ch, phyaddr, 0), ++ chipphyrd(ch, phyaddr, 1), ++ chipphyrd(ch, phyaddr, 2), ++ chipphyrd(ch, phyaddr, 3)); ++ bcm_bprintf(b, "phy4 0x%x phy5 0x%x phy24 0x%x phy25 0x%x\n", ++ chipphyrd(ch, phyaddr, 4), ++ chipphyrd(ch, phyaddr, 5), ++ chipphyrd(ch, phyaddr, 24), ++ chipphyrd(ch, phyaddr, 25)); ++ } ++ ++} ++ ++static void ++gmac_clearmib(ch_t *ch) ++{ ++ volatile uint32 *ptr; ++ ++ /* enable clear on read */ ++ OR_REG(ch->osh, &ch->regs->devcontrol, DC_MROR); ++ ++ for (ptr = &ch->regs->mib.tx_good_octets; ptr <= &ch->regs->mib.rx_uni_pkts; ptr++) { ++ (void)R_REG(ch->osh, ptr); ++ if (ptr == &ch->regs->mib.tx_q3_octets_high) { ++ ptr++; ++ } ++ } ++ ++ return; ++} ++ ++static void ++gmac_init_reset(ch_t *ch) ++{ ++ OR_REG(ch->osh, &ch->regs->cmdcfg, CC_SR); ++ OSL_DELAY(GMAC_RESET_DELAY); ++} ++ ++static void ++gmac_clear_reset(ch_t *ch) ++{ ++ AND_REG(ch->osh, &ch->regs->cmdcfg, ~CC_SR); ++ OSL_DELAY(GMAC_RESET_DELAY); ++} ++ ++static void ++gmac_reset(ch_t *ch) ++{ ++ uint32 ocmdcfg, cmdcfg; ++ ++ /* put the mac in reset */ ++ gmac_init_reset(ch); ++ ++ /* initialize default config */ ++ ocmdcfg = cmdcfg = R_REG(ch->osh, &ch->regs->cmdcfg); ++ ++ cmdcfg &= ~(CC_TE | CC_RE | CC_RPI | CC_TAI | CC_HD | CC_ML | ++ CC_CFE | CC_RL | CC_RED | CC_PE | CC_TPI | CC_PAD_EN | CC_PF); ++ cmdcfg |= (CC_PROM | CC_NLC | CC_CFE); ++ ++#if defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || \ ++ defined(CONFIG_MACH_SB2) || defined(CONFIG_MACH_GH2) ++ cmdcfg |= (CC_AE | CC_OT | CC_OR); ++#endif ++ ++ if (cmdcfg != ocmdcfg) { ++ W_REG(ch->osh, &ch->regs->cmdcfg, cmdcfg); ++ } ++ ++ /* bring mac out of reset */ ++ gmac_clear_reset(ch); ++} ++ ++static void ++gmac_promisc(ch_t *ch, bool mode) ++{ ++ uint32 cmdcfg; ++ ++ cmdcfg = R_REG(ch->osh, &ch->regs->cmdcfg); ++ ++ /* put the mac in reset */ ++ gmac_init_reset(ch); ++ ++ /* enable or disable promiscuous mode */ ++ if (mode) { ++ cmdcfg |= CC_PROM; ++ } else { ++ cmdcfg &= ~CC_PROM; ++ } ++ ++ W_REG(ch->osh, &ch->regs->cmdcfg, cmdcfg); ++ ++ /* bring mac out of reset */ ++ gmac_clear_reset(ch); ++} ++ ++static int ++gmac_speed(ch_t *ch, uint32 speed) ++{ ++ uint32 cmdcfg; ++ uint32 hd_ena = 0; ++#if (defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_HR3)) ++ uint32_t sdctl; ++ uint32 set_speed = speed; ++#endif /* CONFIG_MACH_GH || CONFIG_MACH_HR3 */ ++ ++ switch (speed) { ++ case ET_10HALF: ++ hd_ena = CC_HD; ++ /* FALLTHRU */ ++ ++ case ET_10FULL: ++ speed = 0; ++ break; ++ ++ case ET_100HALF: ++ hd_ena = CC_HD; ++ /* FALLTHRU */ ++ ++ case ET_100FULL: ++ speed = 1; ++ break; ++ ++ case ET_1000FULL: ++ speed = 2; ++ break; ++ ++ case ET_1000HALF: ++ ET_ERROR(("et%d: gmac_speed: supports 1000 mbps full duplex only\n", ++ ch->etc->unit)); ++ return (FAILURE); ++ ++ case ET_2500FULL: ++ speed = 3; ++ break; ++ ++ default: ++ ET_ERROR(("et%d: gmac_speed: speed %d not supported\n", ++ ch->etc->unit, speed)); ++ return (FAILURE); ++ } ++ ++ cmdcfg = R_REG(ch->osh, &ch->regs->cmdcfg); ++ ++ /* put mac in reset */ ++ gmac_init_reset(ch); ++ ++ /* set the speed */ ++ cmdcfg &= ~(CC_ES_MASK | CC_HD); ++ cmdcfg |= ((speed << CC_ES_SHIFT) | hd_ena); ++ ++#if defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || \ ++ defined(CONFIG_MACH_SB2) || defined(CONFIG_MACH_GH2) ++ cmdcfg |= (CC_AE | CC_OT | CC_OR); ++#endif ++ ++ W_REG(ch->osh, &ch->regs->cmdcfg, cmdcfg); ++ ++ /* bring mac out of reset */ ++ gmac_clear_reset(ch); ++ ++#if (defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_HR3)) ++ sdctl = R_REG(ch->osh, &ch->regs->serdes_ctl); ++ sdctl &= ~(SC_FORCE_SPD_STRAP_MASK); ++ switch (set_speed) { ++ case ET_1000FULL: ++ sdctl |= SC_FORCE_SPD_1G_VAL; ++ break; ++ case ET_100FULL: ++ case ET_100HALF: ++ sdctl |= SC_FORCE_SPD_100M_VAL; ++ break; ++ default: ++ break; ++ } ++ W_REG(ch->osh, &ch->regs->serdes_ctl, sdctl); ++ ++ udelay(1000); ++#endif /* CONFIG_MACH_GH || CONFIG_MACH_HR3 */ ++ ++ return (SUCCESS); ++} ++ ++static void ++gmac_macloopback(ch_t *ch, bool on) ++{ ++ uint32 ocmdcfg, cmdcfg; ++ ++ ocmdcfg = cmdcfg = R_REG(ch->osh, &ch->regs->cmdcfg); ++ ++ /* put mac in reset */ ++ gmac_init_reset(ch); ++ ++ /* set/clear the mac loopback mode */ ++ if (on) { ++ cmdcfg |= CC_ML; ++ } else { ++ cmdcfg &= ~CC_ML; ++ } ++ ++ if (cmdcfg != ocmdcfg) { ++ W_REG(ch->osh, &ch->regs->cmdcfg, cmdcfg); ++ } ++ ++ /* bring mac out of reset */ ++ gmac_clear_reset(ch); ++} ++ ++static int ++gmac_loopback(ch_t *ch, uint32 mode) ++{ ++ switch (mode) { ++ case LOOPBACK_MODE_DMA: ++ /* to enable loopback for any channel set the loopback ++ * enable bit in xmt0control register. ++ */ ++ dma_fifoloopbackenable(ch->di[TX_Q0]); ++ break; ++ ++ case LOOPBACK_MODE_MAC: ++ gmac_macloopback(ch, TRUE); ++ break; ++ ++ case LOOPBACK_MODE_NONE: ++ gmac_macloopback(ch, FALSE); ++ break; ++ ++ default: ++ ET_ERROR(("et%d: gmac_loopaback: Unknown loopback mode %d\n", ++ ch->etc->unit, mode)); ++ return (FAILURE); ++ } ++ ++ return (SUCCESS); ++} ++ ++static void ++gmac_enable(ch_t *ch) ++{ ++ uint32 cmdcfg; ++ gmacregs_t *regs; ++ ++ regs = ch->regs; ++ ++ cmdcfg = R_REG(ch->osh, &ch->regs->cmdcfg); ++ ++ /* put mac in reset */ ++ gmac_init_reset(ch); ++ ++ cmdcfg |= CC_SR; ++ ++ /* first deassert rx_ena and tx_ena while in reset */ ++ cmdcfg &= ~(CC_RE | CC_TE); ++ W_REG(ch->osh, ®s->cmdcfg, cmdcfg); ++ ++ /* bring mac out of reset */ ++ gmac_clear_reset(ch); ++ ++ /* enable the mac transmit and receive paths now */ ++ OSL_DELAY(2); ++ cmdcfg &= ~CC_SR; ++ cmdcfg |= (CC_RE | CC_TE); ++ ++ /* assert rx_ena and tx_ena when out of reset to enable the mac */ ++ W_REG(ch->osh, ®s->cmdcfg, cmdcfg); ++ ++ /* request ht clock */ ++ OR_REG(ch->osh, ®s->clk_ctl_st, CS_FH); ++ ++ return; ++} ++ ++static void ++gmac_txflowcontrol(ch_t *ch, bool on) ++{ ++ uint32 cmdcfg; ++ ++ cmdcfg = R_REG(ch->osh, &ch->regs->cmdcfg); ++ ++ /* put the mac in reset */ ++ gmac_init_reset(ch); ++ ++ /* to enable tx flow control clear the rx pause ignore bit */ ++ if (on) { ++ cmdcfg &= ~CC_RPI; ++ } else { ++ cmdcfg |= CC_RPI; ++ } ++ ++ W_REG(ch->osh, &ch->regs->cmdcfg, cmdcfg); ++ ++ /* bring mac out of reset */ ++ gmac_clear_reset(ch); ++} ++ ++ ++#if defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || \ ++ defined(CONFIG_MACH_SB2) || defined(CONFIG_MACH_GH2) || defined(CONFIG_MACH_WH2) ++static void ++gmac_serdes_init(ch_t *ch) ++{ ++ uint32_t sdctl, sdstat0, sdstat1; ++ gmacregs_t *regs; ++ ++ regs = ch->regs; ++ ++ ET_TRACE(("%s enter\n", __FUNCTION__)); ++ ++ sdctl = R_REG(ch->osh, &ch->regs->serdes_ctl); ++ sdstat0 = R_REG(ch->osh, &ch->regs->serdes_status0); ++ sdstat1 = R_REG(ch->osh, &ch->regs->serdes_status1); ++ ++ /* ++ * Bring up both digital and analog clocks ++ * ++ * NOTE: Many MAC registers are not accessible until the PLL is locked. ++ * An S-Channel timeout will occur before that. ++ */ ++ ++ sdctl = (SC_TX1G_FIFO_RST_VAL|SC_FORCE_SPD_STRAP_VAL); ++#if defined(CONFIG_MACH_HX4) ++ sdctl |= (SC_REFSEL_VAL|SC_REF_TERM_SEL_MASK); ++#elif defined(CONFIG_MACH_KT2) ++ sdctl |= SC_REF_TERM_SEL_MASK; ++#endif /* (defined(CONFIG_MACH_HX4) */ ++ W_REG(ch->osh, &ch->regs->serdes_ctl, sdctl); ++ ++ udelay(1000); ++ ++ sdctl = R_REG(ch->osh, &ch->regs->serdes_ctl); ++ sdctl |= (SC_IDDQ_MASK|SC_PWR_DOWN_MASK); ++ W_REG(ch->osh, &ch->regs->serdes_ctl, sdctl); ++ ++ sdctl = R_REG(ch->osh, &ch->regs->serdes_ctl); ++ sdctl &= ~(SC_IDDQ_MASK|SC_PWR_DOWN_MASK); ++ W_REG(ch->osh, &ch->regs->serdes_ctl, sdctl); ++ ++ /* Bring hardware out of reset */ ++ sdctl = R_REG(ch->osh, &ch->regs->serdes_ctl); ++ sdctl |= (SC_RSTB_HW_MASK); ++ W_REG(ch->osh, &ch->regs->serdes_ctl, sdctl); ++ ++ /* Bring MDIOREGS out of reset */ ++ sdctl = R_REG(ch->osh, &ch->regs->serdes_ctl); ++ sdctl |= (SC_RSTB_MDIOREGS_MASK); ++ W_REG(ch->osh, &ch->regs->serdes_ctl, sdctl); ++ ++ udelay(1000); ++ ++ /* Bring PLL out of reset */ ++ sdctl = R_REG(ch->osh, &ch->regs->serdes_ctl); ++ sdctl |= (SC_RSTB_PLL_MASK); ++ W_REG(ch->osh, &ch->regs->serdes_ctl, sdctl); ++ ++ udelay(1000); ++ ++ sdctl = R_REG(ch->osh, &ch->regs->serdes_ctl); ++ sdstat0 = R_REG(ch->osh, &ch->regs->serdes_status0); ++ sdstat1 = R_REG(ch->osh, &ch->regs->serdes_status1); ++ ++ return; ++} ++#endif /* defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || \ ++ defined(CONFIG_MACH_SB2) || defined(CONFIG_MACH_GH2) || defined(CONFIG_MACH_WH2) */ ++ ++static void ++gmac_miiconfig(ch_t *ch) ++{ ++ /* BCM53010 GMAC DevStatus register has different definition of "Interface Mode" ++ * Bit 12:8 "interface_mode" This field is programmed through IDM control bits [6:2] ++ * ++ * Bit 0 : SOURCE_SYNC_MODE_EN - If set, Rx line clock input will be used by Unimac for ++ * sampling data.If this is reset, PLL reference clock (Clock 250 or Clk 125 based ++ * on CLK_250_SEL) will be used as receive side line clock. ++ * Bit 1 : DEST_SYNC_MODE_EN - If this is reset, PLL reference clock input (Clock 250 or ++ * Clk 125 based on CLK_250_SEL) will be used as transmit line clock. ++ * If this is set, TX line clock input (from external switch/PHY) is used as ++ * transmit line clock. ++ * Bit 2 : TX_CLK_OUT_INVERT_EN - If set, this will invert the TX clock out of AMAC. ++ * Bit 3 : DIRECT_GMII_MODE - If direct gmii is set to 0, then only 25 MHz clock needs to ++ * be fed at 25MHz reference clock input, for both 10/100 Mbps speeds. ++ * Unimac will internally divide the clock to 2.5 MHz for 10 Mbps speed ++ * Bit 4 : CLK_250_SEL - When set, this selects 250Mhz reference clock input and hence ++ * Unimac line rate will be 2G. ++ * If reset, this selects 125MHz reference clock input. ++ */ ++ ++ if (ch->etc->forcespeed == ET_AUTO) { ++ if (ch->etc->deviceid == BCM56150_CHIP_ID) { ++ gmac_speed(ch, ET_100FULL); ++ } else { ++ gmac_speed(ch, ET_1000FULL); ++ } ++ } else { ++ gmac_speed(ch, ch->etc->forcespeed); ++ } ++} ++ ++#ifdef CONFIG_SERDES_ASYMMETRIC_MODE ++void ++gmac_serdes_asym_mode(etc_info_t *etcptrs[]) ++{ ++ etc_info_t *etc; ++ ++ etc = etcptrs[0]; ++ ++ /* initialize serdes */ ++ gmac_serdes_init(etc->ch); ++ serdes_reset_core(etc->unit, etc->int_phyaddr); ++ ++ /* initialize lane 0 */ ++ serdes_set_asym_mode(etc->unit, etc->int_phyaddr); ++ serdes_init(etc->unit, etc->int_phyaddr); ++ serdes_speeddpx_set(etc->unit, etc->int_phyaddr, etc->speed, etc->duplex); ++ /* initialize lane 1 */ ++ etc = etcptrs[1]; ++ if (etc->linkstate) { ++ serdes_set_asym_mode(etc->unit, etc->int_phyaddr); ++ serdes_init(etc->unit, etc->int_phyaddr); ++ serdes_speeddpx_set(etc->unit, etc->int_phyaddr, etc->speed, etc->duplex); ++ } ++ ++ /* ++ * The 4-lane serdes is shared between XLDK and SDK. XLDK has to ++ * initialize the 3rd lane (phy address 3) that is used by SDK. ++ */ ++ serdes_init(etc->unit, 3); ++ ++ /* start PLL */ ++ serdes_start_pll(etc->unit, 1); ++} ++#endif /* CONFIG_SERDES_ASYMMETRIC_MODE */ ++ ++ ++static void ++chipreset(ch_t *ch) ++{ ++ gmacregs_t *regs; ++ uint32 idx, sflags, flagbits = 0; ++ ++ ET_TRACE(("et%d: chipreset\n", ch->etc->unit)); ++ ++ regs = ch->regs; ++ ++ if (!si_iscoreup(ch->sih)) { ++ /* power on reset: reset the enet core */ ++ goto chipinreset; ++ } ++ ++ /* Reset other three GMAC cores if needed */ ++ for (idx = 0; idx < IPROC_NUM_GMACS; idx++) { ++ /* As northstar requirement, we have to reset all GAMCs before accessing them. ++ * et_probe() call pci_enable_device() for etx and do si_core_reset for GAMCx only. ++ * then the other three GAMC didn't reset. ++ * We do it here. ++ */ ++ si_setcore(ch->sih, GMAC_CORE_ID, idx); ++ if (!si_iscoreup(ch->sih)) { ++ ET_TRACE(("et%d: reset NorthStar GMAC[%d] core\n", ch->etc->unit, idx)); ++ si_core_reset(ch->sih, flagbits, 0); ++ } ++ } ++ si_setcore(ch->sih, GMAC_CORE_ID, 0); ++ ++ /* update software counters before resetting the chip */ ++ if (ch->mibgood) { ++ chipstatsupd(ch); ++ } ++ ++ /* reset the tx dma engines */ ++ for (idx = 0; idx < NUMTXQ; idx++) { ++ if (ch->di[idx]) { ++ ET_TRACE(("et%d: resetting tx dma%d\n", ch->etc->unit, idx)); ++ dma_txreset(ch->di[idx]); ++ } ++ } ++ ++ /* set gmac into loopback mode to ensure no rx traffic */ ++ gmac_loopback(ch, LOOPBACK_MODE_MAC); ++ OSL_DELAY(1); ++ ++ /* reset the rx dma engine */ ++ if (ch->di[RX_Q0]) { ++ ET_TRACE(("et%d: resetting rx dma\n", ch->etc->unit)); ++ dma_rxreset(ch->di[RX_Q0]); ++ } ++ ++ /* clear the multicast filter table */ ++ gmac_mf_cleanup(ch); ++ ++chipinreset: ++ sflags = si_core_sflags(ch->sih, 0, 0); ++ if (sflags & SISF_SW_ATTACHED) { ++ ET_TRACE(("et%d: internal switch attached\n", ch->etc->unit)); ++ flagbits = SICF_SWCLKE; ++ if (!ch->etc->robo) { ++ ET_TRACE(("et%d: reseting switch\n", ch->etc->unit)); ++ flagbits |= SICF_SWRST; ++ } ++ } ++ ++ /* Reset all GMAC cores */ ++ for (idx = 0; idx < IPROC_NUM_GMACS; idx++) { ++ /* As northstar requirement, we have to reset all GAMCs before accessing them. ++ * et_probe() call pci_enable_device() for etx and do si_core_reset for GAMCx only. ++ * then the other three GAMC didn't reset. ++ * We do it here. ++ */ ++ si_setcore(ch->sih, GMAC_CORE_ID, idx); ++ if (!si_iscoreup(ch->sih)) { ++ ET_TRACE(("et%d: reset NorthStar GMAC[%d] core\n", ch->etc->unit, idx)); ++ si_core_reset(ch->sih, flagbits, 0); ++ } ++ } ++ si_setcore(ch->sih, GMAC_CORE_ID, 0); ++ ++ if ((sflags & SISF_SW_ATTACHED) && (!ch->etc->robo)) { ++ ET_TRACE(("et%d: taking switch out of reset\n", ch->etc->unit)); ++ si_core_cflags(ch->sih, SICF_SWRST, 0); ++ } ++ ++ /* reset gmac */ ++ gmac_reset(ch); ++ ++ /* clear mib */ ++ gmac_clearmib(ch); ++ ch->mibgood = TRUE; ++ ++ /* set mdc_transition_en */ ++ OR_REG(ch->osh, ®s->phycontrol, PC_MTE); ++ ++ /* Read the devstatus to figure out the configuration mode of ++ * the interface. Set the speed to 100 if the switch interface ++ * is mii/rmii. ++ */ ++ gmac_miiconfig(ch); ++ ++ /* clear persistent sw intstatus */ ++ ch->intstatus = 0; ++} ++ ++/* ++ * Lookup a multicast address in the filter hash table. ++ */ ++static int ++gmac_mf_lkup(ch_t *ch, struct ether_addr *mcaddr) ++{ ++ mflist_t *ptr; ++ ++ /* find the multicast address */ ++ for (ptr = ch->mf.bucket[GMAC_MCADDR_HASH(mcaddr)]; ptr != NULL; ptr = ptr->next) { ++ if (!ETHER_MCADDR_CMP(&ptr->mc_addr, mcaddr)) { ++ return (SUCCESS); ++ } ++ } ++ ++ return (FAILURE); ++} ++ ++/* ++ * Add a multicast address to the filter hash table. ++ */ ++static int ++gmac_mf_add(ch_t *ch, struct ether_addr *mcaddr) ++{ ++ uint32 hash; ++ mflist_t *entry; ++#ifdef BCMDBG ++ char mac[ETHER_ADDR_STR_LEN]; ++#endif /* BCMDBG */ ++ ++ /* add multicast addresses only */ ++ if (!ETHER_ISMULTI(mcaddr)) { ++ ET_ERROR(("et%d: adding invalid multicast address %s\n", ++ ch->etc->unit, bcm_ether_ntoa(mcaddr, mac))); ++ return (FAILURE); ++ } ++ ++ /* discard duplicate add requests */ ++ if (gmac_mf_lkup(ch, mcaddr) == SUCCESS) { ++ ET_ERROR(("et%d: adding duplicate mcast filter entry\n", ch->etc->unit)); ++ return (FAILURE); ++ } ++ ++ /* allocate memory for list entry */ ++ entry = MALLOC(ch->osh, sizeof(mflist_t)); ++ if (entry == NULL) { ++ ET_ERROR(("et%d: out of memory allocating mcast filter entry\n", ch->etc->unit)); ++ return (FAILURE); ++ } ++ ++ /* add the entry to the hash bucket */ ++ ether_copy(mcaddr, &entry->mc_addr); ++ hash = GMAC_MCADDR_HASH(mcaddr); ++ entry->next = ch->mf.bucket[hash]; ++ ch->mf.bucket[hash] = entry; ++ ++ return (SUCCESS); ++} ++ ++/* ++ * Cleanup the multicast filter hash table. ++ */ ++static void ++gmac_mf_cleanup(ch_t *ch) ++{ ++ mflist_t *ptr, *tmp; ++ int32 idx; ++ ++ for (idx = 0; idx < GMAC_HASHT_SIZE; idx++) { ++ ptr = ch->mf.bucket[idx]; ++ while (ptr) { ++ tmp = ptr; ++ ptr = ptr->next; ++ MFREE(ch->osh, tmp, sizeof(mflist_t)); ++ } ++ ch->mf.bucket[idx] = NULL; ++ } ++} ++ ++/* ++ * Initialize all the chip registers. If dma mode, init tx and rx dma engines ++ * but leave the devcontrol tx and rx (fifos) disabled. ++ */ ++static void ++chipinit(ch_t *ch, uint options) ++{ ++ etc_info_t *etc; ++ gmacregs_t *regs; ++ uint idx; ++ ++ regs = ch->regs; ++ etc = ch->etc; ++ ++ ET_TRACE(("et%d: chipinit\n", etc->unit)); ++ ++ /* enable one rx interrupt per received frame */ ++ W_REG(ch->osh, ®s->intrecvlazy, (1 << IRL_FC_SHIFT)); ++ ++ /* enable 802.3x tx flow control (honor received PAUSE frames) */ ++ gmac_txflowcontrol(ch, TRUE); ++ ++ /* enable/disable promiscuous mode */ ++ gmac_promisc(ch, etc->promisc); ++ ++ /* set our local address */ ++ W_REG(ch->osh, ®s->macaddrhigh, ++ hton32(*(uint32 *)&etc->cur_etheraddr.octet[0])); ++ W_REG(ch->osh, ®s->macaddrlow, ++ hton16(*(uint16 *)&etc->cur_etheraddr.octet[4])); ++ ++ if (!etc->promisc) { ++ /* gmac doesn't have a cam, hence do the multicast address filtering ++ * in the software ++ */ ++ /* allmulti or a list of discrete multicast addresses */ ++ if (!etc->allmulti && etc->nmulticast) { ++ for (idx = 0; idx < etc->nmulticast; idx++) { ++ (void)gmac_mf_add(ch, &etc->multicast[idx]); ++ } ++ } ++ } ++ ++ /* optionally enable mac-level loopback */ ++ if (etc->loopbk) { ++ gmac_loopback(ch, LOOPBACK_MODE_MAC); ++ } else { ++ gmac_loopback(ch, LOOPBACK_MODE_NONE); ++ } ++ ++ /* set max frame lengths - account for possible vlan tag */ ++ W_REG(ch->osh, ®s->rxmaxlength, BCM_ETHER_MAX_LEN + 32); ++ ++ /* ++ * Optionally, disable phy autonegotiation and force our speed/duplex ++ * or constrain our advertised capabilities. ++ */ ++ if (etc->forcespeed != ET_AUTO) { ++ gmac_speed(ch, etc->forcespeed); ++ chipphyforce(ch, etc->phyaddr); ++ switch (etc->forcespeed) { ++ case ET_1000FULL: ++ etc->speed = 1000; ++ etc->duplex = 1; ++ break; ++ case ET_1000HALF: ++ etc->speed = 1000; ++ etc->duplex = 0; ++ break; ++ case ET_100FULL: ++ etc->speed = 100; ++ etc->duplex = 1; ++ break; ++ case ET_100HALF: ++ etc->speed = 100; ++ etc->duplex = 0; ++ break; ++ case ET_10FULL: ++ etc->speed = 10; ++ etc->duplex = 1; ++ break; ++ case ET_10HALF: ++ etc->speed = 10; ++ etc->duplex = 0; ++ break; ++ default: ++ break; ++ } ++ } else if (etc->advertise && etc->needautoneg) { ++ chipphyadvertise(ch, etc->phyaddr); ++ } ++ /* enable the overflow continue feature and disable parity */ ++ dma_ctrlflags(ch->di[0], DMA_CTRL_ROC | DMA_CTRL_PEN /* mask */, ++ DMA_CTRL_ROC /* value */); ++ ++ if (options & ET_INIT_FULL) { ++ /* initialize the tx and rx dma channels */ ++ for (idx = 0; idx < NUMTXQ; idx++) { ++ dma_txinit(ch->di[idx]); ++ } ++ dma_rxinit(ch->di[RX_Q0]); ++ ++ /* post dma receive buffers */ ++ dma_rxfill(ch->di[RX_Q0]); ++ ++ /* lastly, enable interrupts */ ++ if (options & ET_INIT_INTRON) { ++ et_intrson(etc->et); ++ } ++ } else { ++ dma_rxenable(ch->di[RX_Q0]); ++ } ++ ++ /* turn on the emac */ ++ gmac_enable(ch); ++} ++ ++/* dma transmit */ ++static bool BCMFASTPATH ++chiptx(ch_t *ch, void *p0) ++{ ++ int error, len; ++ uint32 q = TX_Q0; ++ ++ ET_TRACE(("et%d: chiptx\n", ch->etc->unit)); ++ ET_LOG("et%d: chiptx", ch->etc->unit, 0); ++ ++ len = PKTLEN(ch->osh, p0); ++ ++ /* check tx max length */ ++ if (len > (BCM_ETHER_MAX_LEN + 32)) { ++ ET_ERROR(("et%d: chiptx: max frame length exceeded\n", ++ ch->etc->unit)); ++ PKTFREE(ch->osh, p0, TRUE); ++ return FALSE; ++ } ++ ++ /* gmac rev 0 workaround: unimac can only transmit frames of ++ * length 17 bytes or greater. so pad the frame and send a ++ * 17 byte frame. to do the padding just modify the packet ++ * length that we provide to the dma. unimac does the extra ++ * padding * required to send 64 byte frames. ++ */ ++ if ((len < GMAC_MIN_FRAMESIZE) && (ch->etc->corerev == 0)) { ++ PKTSETLEN(ch->osh, p0, GMAC_MIN_FRAMESIZE); ++ } ++ ++ ASSERT(q < NUMTXQ); ++ ++ /* if tx completion intr is disabled then do the reclaim ++ * once every few frames transmitted. ++ */ ++ if ((ch->etc->txframes[q] & ch->etc->txrec_thresh) == 1) { ++ dma_txreclaim(ch->di[q], HNDDMA_RANGE_TRANSMITTED); ++ } ++ ++ error = dma_txfast(ch->di[q], p0, TRUE); ++ ++ if (error) { ++ ET_ERROR(("et%d: chiptx: out of txds\n", ch->etc->unit)); ++ ch->etc->txnobuf++; ++ return FALSE; ++ } ++ ++ ch->etc->txframes[q]++; ++ ++ if ((len < GMAC_MIN_FRAMESIZE) && (ch->etc->corerev == 0)) { ++ if (skb_is_nonlinear((struct sk_buff*)p0)) { ++ printk("Modified nonlinear skb (et_ctf_pipeline_loopback) - not calling skb_trim\n"); ++ } else { ++ /* set back the orig length */ ++ PKTSETLEN(ch->osh, p0, len); ++ } ++ } ++ ++ return TRUE; ++} ++ ++/* reclaim completed transmit descriptors and packets */ ++static void BCMFASTPATH ++chiptxreclaim(ch_t *ch, bool forceall) ++{ ++ int32 idx; ++ ++ ET_TRACE(("et%d: chiptxreclaim\n", ch->etc->unit)); ++ ++ for (idx = 0; idx < NUMTXQ; idx++) { ++ dma_txreclaim(ch->di[idx], forceall ? HNDDMA_RANGE_ALL : HNDDMA_RANGE_TRANSMITTED); ++ ch->intstatus &= ~(I_XI0 << idx); ++ } ++} ++ ++/* dma receive: returns a pointer to the next frame received, or NULL if there are no more */ ++static void * BCMFASTPATH ++chiprx(ch_t *ch) ++{ ++ void *p; ++ struct ether_addr *da; ++ ++ ET_TRACE(("et%d: chiprx\n", ch->etc->unit)); ++ ET_LOG("et%d: chiprx", ch->etc->unit, 0); ++ ++ if (dma_rxstopped(ch->di[RX_Q0])) { ++ ch->etc->rxdmastopped++; ++ } ++ ++ /* gmac doesn't have a cam to do address filtering. so we implement ++ * the multicast address filtering here. ++ */ ++ while ((p = dma_rx(ch->di[RX_Q0])) != NULL) { ++ /* check for overflow error packet */ ++ if (RXH_FLAGS(ch->etc, PKTDATA(ch->osh, p)) & GRXF_OVF) { ++ PKTFREE(ch->osh, p, FALSE); ++ ch->etc->rxoflodiscards++; ++ continue; ++ } ++ ++#ifdef GMAC_RATE_LIMITING ++ /* rate limiting */ ++ /* printf("et%d: chiprx RXH_PT(0x%x)\n", ch->etc->unit, RXH_PT(ch->etc, PKTDATA(ch->osh, p))); */ ++ if (RXH_PT(ch->etc, PKTDATA(ch->osh, p)) == 2) ++ ch->etc->rx_bc_frame_cnt++; ++ if (ch->etc->rl_stopping_broadcasts) { ++ /* check if broadcast packet */ ++ if (RXH_PT(ch->etc, PKTDATA(ch->osh, p)) == 2) { ++ /* broadcast packet */ ++ PKTFREE(ch->osh, p, FALSE); ++ ch->etc->rl_dropped_bc_packets++; ++ ch->etc->rl_dropped_packets++; ++ continue; ++ } ++ } else if (ch->etc->rl_stopping_all_packets) { ++ PKTFREE(ch->osh, p, FALSE); ++ ch->etc->rl_dropped_all_packets++; ++ ch->etc->rl_dropped_packets++; ++ continue; ++ } ++#endif /* GMAC_RATE_LIMITING */ ++ ++ if (ch->etc->allmulti) { ++ return (p); ++ } else { ++ /* skip the rx header */ ++ PKTPULL(ch->osh, p, HWRXOFF); ++ ++ /* do filtering only for multicast packets when allmulti is false */ ++ da = (struct ether_addr *)PKTDATA(ch->osh, p); ++ if (!ETHER_ISMULTI(da) || ++ (gmac_mf_lkup(ch, da) == SUCCESS) || ETHER_ISBCAST(da)) { ++ PKTPUSH(ch->osh, p, HWRXOFF); ++ return (p); ++ } ++ PKTFREE(ch->osh, p, FALSE); ++ } ++ } ++ ++ ch->intstatus &= ~I_RI; ++ ++ /* post more rx buffers since we consumed a few */ ++ dma_rxfill(ch->di[RX_Q0]); ++ ++ return (NULL); ++} ++ ++/* reclaim completed dma receive descriptors and packets */ ++static void ++chiprxreclaim(ch_t *ch) ++{ ++ ET_TRACE(("et%d: chiprxreclaim\n", ch->etc->unit)); ++ dma_rxreclaim(ch->di[RX_Q0]); ++ ch->intstatus &= ~I_RI; ++} ++ ++/* allocate and post dma receive buffers */ ++static void BCMFASTPATH ++chiprxfill(ch_t *ch) ++{ ++ ET_TRACE(("et%d: chiprxfill\n", ch->etc->unit)); ++ ET_LOG("et%d: chiprxfill", ch->etc->unit, 0); ++ dma_rxfill(ch->di[RX_Q0]); ++} ++ ++#ifdef DBG_CHECK_ERR ++/* get current and pending interrupt events */ ++static void ++check_errs(ch_t *ch) ++{ ++ static uint32 crserrs = 0; ++ uint32 err; ++ ++ /* read the interrupt status register */ ++ err = R_REG(ch->osh, &ch->regs->mib.tx_jabber_pkts); ++ if (err) { ++ printk("%s tx_jabber_pkts (0x%x)\n", __FUNCTION__, err); ++ } ++ ++ err = R_REG(ch->osh, &ch->regs->mib.tx_oversize_pkts); ++ if (err) { ++ printk("%s tx_oversize_pkts (0x%x)\n", __FUNCTION__, err); ++ } ++ ++ err = R_REG(ch->osh, &ch->regs->mib.tx_fragment_pkts); ++ if (err) { ++ printk("%s tx_fragment_pkts (0x%x)\n", __FUNCTION__, err); ++ } ++ ++ err = R_REG(ch->osh, &ch->regs->mib.tx_underruns); ++ if (err) { ++ printk("%s tx_underruns (0x%x)\n", __FUNCTION__, err); ++ } ++ ++ err = R_REG(ch->osh, &ch->regs->mib.tx_total_cols); ++ if (err) { ++ printk("%s tx_total_cols (0x%x)\n", __FUNCTION__, err); ++ } ++ ++ err = R_REG(ch->osh, &ch->regs->mib.tx_single_cols); ++ if (err) { ++ printk("%s tx_single_cols (0x%x)\n", __FUNCTION__, err); ++ } ++ ++ err = R_REG(ch->osh, &ch->regs->mib.tx_multiple_cols); ++ if (err) { ++ printk("%s tx_multiple_cols (0x%x)\n", __FUNCTION__, err); ++ } ++ ++ err = R_REG(ch->osh, &ch->regs->mib.tx_excessive_cols); ++ if (err) { ++ printk("%s tx_excessive_cols (0x%x)\n", __FUNCTION__, err); ++ } ++ ++ err = R_REG(ch->osh, &ch->regs->mib.tx_late_cols); ++ if (err) { ++ printk("%s tx_late_cols (0x%x)\n", __FUNCTION__, err); ++ } ++ ++ err = R_REG(ch->osh, &ch->regs->mib.tx_defered); ++ if (err) { ++ printk("%s tx_defered (0x%x)\n", __FUNCTION__, err); ++ } ++ ++ err = R_REG(ch->osh, &ch->regs->mib.tx_carrier_lost); ++ crserrs += err; ++ if (crserrs > 100) { ++ printk("%s tx_carrier_lost crserrs(0x%x)\n", __FUNCTION__, crserrs); ++ crserrs = 0; ++ } ++ ++ err = R_REG(ch->osh, &ch->regs->mib.tx_pause_pkts); ++ if (err) { ++ printk("%s tx_pause_pkts (0x%x)\n", __FUNCTION__, err); ++ } ++ ++ err = R_REG(ch->osh, &ch->regs->mib.rx_jabber_pkts); ++ if (err) { ++ printk("%s rx_jabber_pkts (0x%x)\n", __FUNCTION__, err); ++ } ++ ++ err = R_REG(ch->osh, &ch->regs->mib.rx_oversize_pkts); ++ if (err) { ++ printk("%s rx_oversize_pkts (0x%x)\n", __FUNCTION__, err); ++ } ++ ++ err = R_REG(ch->osh, &ch->regs->mib.rx_fragment_pkts); ++ if (err) { ++ printk("%s rx_fragment_pkts (0x%x)\n", __FUNCTION__, err); ++ } ++ ++ err = R_REG(ch->osh, &ch->regs->mib.rx_missed_pkts); ++ if (err) { ++ printk("%s rx_missed_pkts (0x%x)\n", __FUNCTION__, err); ++ } ++ ++ err = R_REG(ch->osh, &ch->regs->mib.rx_crc_align_errs); ++ if (err) { ++ printk("%s rx_crc_align_errs (0x%x)\n", __FUNCTION__, err); ++ } ++ ++ err = R_REG(ch->osh, &ch->regs->mib.rx_undersize); ++ if (err) { ++ printk("%s rx_undersize (0x%x)\n", __FUNCTION__, err); ++ } ++ ++ err = R_REG(ch->osh, &ch->regs->mib.rx_crc_errs); ++ if (err) { ++ printk("%s rx_crc_errs (0x%x)\n", __FUNCTION__, err); ++ } ++ ++ err = R_REG(ch->osh, &ch->regs->mib.rx_align_errs); ++ if (err) { ++ printk("%s rx_align_errs (0x%x)\n", __FUNCTION__, err); ++ } ++ ++ err = R_REG(ch->osh, &ch->regs->mib.rx_symbol_errs); ++ if (err) { ++ printk("%s rx_symbol_errs (0x%x)\n", __FUNCTION__, err); ++ } ++ ++ err = R_REG(ch->osh, &ch->regs->mib.rx_pause_pkts); ++ if (err) { ++ printk("%s rx_pause_pkts (0x%x)\n", __FUNCTION__, err); ++ } ++ ++ err = R_REG(ch->osh, &ch->regs->mib.rx_nonpause_pkts); ++ if (err) { ++ printk("%s rx_nonpause_pkts (0x%x)\n", __FUNCTION__, err); ++ } ++ ++ err = R_REG(ch->osh, &ch->regs->mib.rx_sachanges); ++ if (err) { ++ printk("%s rx_sachanges (0x%x)\n", __FUNCTION__, err); ++ } ++ ++ err = R_REG(ch->osh, &ch->regs->dmaregs[0].dmaxmt.status1); ++ if (err & 0xf0000000) { ++ printk("%s dma0 xmit status (0x%x)\n", __FUNCTION__, err); ++ } ++ ++ err = R_REG(ch->osh, &ch->regs->dmaregs[0].dmarcv.status1); ++ if (err & 0xf0000000) { ++ printk("%s dma0 rcv status (0x%x)\n", __FUNCTION__, err); ++ } ++ ++#if defined(CONFIG_MACH_HR2) ++ phy5221_chk_err(ch->etc->unit, ch->etc->phyaddr); ++#endif /* defined(CONFIG_MACH_HR2) */ ++} ++#endif /* DBG_CHECK_ERR */ ++ ++/* get current and pending interrupt events */ ++static int BCMFASTPATH ++chipgetintrevents(ch_t *ch, bool in_isr) ++{ ++ uint32 intstatus; ++ int events; ++ ++ events = 0; ++ ++ /* read the interrupt status register */ ++ intstatus = R_REG(ch->osh, &ch->regs->intstatus); ++ ++ /* defer unsolicited interrupts */ ++ intstatus &= (in_isr ? ch->intmask : ch->def_intmask); ++ ++ if (intstatus != 0) { ++ events = INTR_NEW; ++ } ++ ++ /* or new bits into persistent intstatus */ ++ intstatus = (ch->intstatus |= intstatus); ++ ++ /* return if no events */ ++ if (intstatus == 0) { ++ return (0); ++ } ++ ++#ifdef DBG_CHECK_ERR ++ check_errs(ch); ++#endif /* DBG_CHECK_ERR */ ++ ++ /* convert chip-specific intstatus bits into generic intr event bits */ ++ if (intstatus & I_RI) { ++ events |= INTR_RX; ++ } ++ if (intstatus & (I_XI0 | I_XI1 | I_XI2 | I_XI3)) { ++ events |= INTR_TX; ++ } ++ if (intstatus & I_ERRORS) { ++ events |= INTR_ERROR; ++ } ++ ++ return (events); ++} ++ ++/* enable chip interrupts */ ++static void BCMFASTPATH ++chipintrson(ch_t *ch) ++{ ++ ch->intmask = ch->def_intmask; ++ W_REG(ch->osh, &ch->regs->intmask, ch->intmask); ++} ++ ++/* disable chip interrupts */ ++static void BCMFASTPATH ++chipintrsoff(ch_t *ch) ++{ ++ /* disable further interrupts from gmac */ ++ W_REG(ch->osh, &ch->regs->intmask, 0); ++ (void) R_REG(ch->osh, &ch->regs->intmask); /* sync readback */ ++ ch->intmask = 0; ++ ++ /* clear the interrupt conditions */ ++ W_REG(ch->osh, &ch->regs->intstatus, ch->intstatus); ++} ++ ++/* return true of caller should re-initialize, otherwise false */ ++static bool BCMFASTPATH ++chiperrors(ch_t *ch) ++{ ++ uint32 intstatus; ++ etc_info_t *etc; ++ ++ etc = ch->etc; ++ ++ intstatus = ch->intstatus; ++ ch->intstatus &= ~(I_ERRORS); ++ ++ ET_TRACE(("et%d: chiperrors: intstatus 0x%x\n", etc->unit, intstatus)); ++ ++ if (intstatus & I_PDEE) { ++ ET_ERROR(("et%d: descriptor error\n", etc->unit)); ++ etc->dmade++; ++ } ++ ++ if (intstatus & I_PDE) { ++ ET_ERROR(("et%d: data error\n", etc->unit)); ++ etc->dmada++; ++ } ++ ++ if (intstatus & I_DE) { ++ ET_ERROR(("et%d: descriptor protocol error\n", etc->unit)); ++ etc->dmape++; ++ } ++ ++ if (intstatus & I_RDU) { ++ ET_ERROR(("et%d: receive descriptor underflow\n", etc->unit)); ++ etc->rxdmauflo++; ++ } ++ ++ if (intstatus & I_RFO) { ++ ET_TRACE(("et%d: receive fifo overflow\n", etc->unit)); ++ etc->rxoflo++; ++ } ++ ++ if (intstatus & I_XFU) { ++ ET_ERROR(("et%d: transmit fifo underflow\n", etc->unit)); ++ etc->txuflo++; ++ } ++ ++ /* if overflows or decriptors underflow, don't report it ++ * as an error and provoque a reset ++ */ ++ if (intstatus & ~(I_RDU | I_RFO) & I_ERRORS) { ++ return (TRUE); ++ } ++ ++ return (FALSE); ++} ++ ++static void ++chipstatsupd(ch_t *ch) ++{ ++ etc_info_t *etc; ++ gmacregs_t *regs; ++ volatile uint32 *s; ++ uint32 *d; ++ ++ etc = ch->etc; ++ regs = ch->regs; ++ ++ /* read the mib counters and update the driver maintained software ++ * counters. ++ */ ++ OR_REG(ch->osh, ®s->devcontrol, DC_MROR); ++ for (s = ®s->mib.tx_good_octets, d = &ch->mib.tx_good_octets; ++ s <= ®s->mib.rx_uni_pkts; s++, d++) { ++ *d += R_REG(ch->osh, s); ++ if (s == &ch->regs->mib.tx_q3_octets_high) { ++ s++; ++ d++; ++ } ++ } ++ ++ /* ++ * Aggregate transmit and receive errors that probably resulted ++ * in the loss of a frame are computed on the fly. ++ * ++ * We seem to get lots of tx_carrier_lost errors when flipping ++ * speed modes so don't count these as tx errors. ++ * ++ * Arbitrarily lump the non-specific dma errors as tx errors. ++ */ ++ etc->txerror = ch->mib.tx_jabber_pkts + ch->mib.tx_oversize_pkts ++ + ch->mib.tx_underruns + ch->mib.tx_excessive_cols ++ + ch->mib.tx_late_cols + etc->txnobuf + etc->dmade ++ + etc->dmada + etc->dmape + etc->txuflo; ++ etc->rxerror = ch->mib.rx_jabber_pkts + ch->mib.rx_oversize_pkts ++ + ch->mib.rx_missed_pkts + ch->mib.rx_crc_align_errs ++ + ch->mib.rx_undersize + ch->mib.rx_crc_errs ++ + ch->mib.rx_align_errs ++ + etc->rxnobuf + etc->rxdmauflo + etc->rxoflo + etc->rxbadlen; ++ etc->rxgiants = (ch->di[RX_Q0])->rxgiants; ++} ++ ++static void ++chipdumpmib(ch_t *ch, struct bcmstrbuf *b, bool clear) ++{ ++ gmacmib_t *m; ++ ++ m = &ch->mib; ++ ++ if (clear) { ++ bzero((char *)m, sizeof(gmacmib_t)); ++ return; ++ } ++ ++ bcm_bprintf(b, "tx_broadcast_pkts %d tx_multicast_pkts %d tx_jabber_pkts %d " ++ "tx_oversize_pkts %d\n", ++ m->tx_broadcast_pkts, m->tx_multicast_pkts, ++ m->tx_jabber_pkts, ++ m->tx_oversize_pkts); ++ bcm_bprintf(b, "tx_fragment_pkts %d tx_underruns %d\n", ++ m->tx_fragment_pkts, m->tx_underruns); ++ bcm_bprintf(b, "tx_total_cols %d tx_single_cols %d tx_multiple_cols %d " ++ "tx_excessive_cols %d\n", ++ m->tx_total_cols, m->tx_single_cols, m->tx_multiple_cols, ++ m->tx_excessive_cols); ++ bcm_bprintf(b, "tx_late_cols %d tx_defered %d tx_carrier_lost %d tx_pause_pkts %d\n", ++ m->tx_late_cols, m->tx_defered, m->tx_carrier_lost, ++ m->tx_pause_pkts); ++ ++ /* receive stat counters */ ++ /* hardware mib pkt and octet counters wrap too quickly to be useful */ ++ bcm_bprintf(b, "rx_broadcast_pkts %d rx_multicast_pkts %d rx_jabber_pkts %d " ++ "rx_oversize_pkts %d\n", ++ m->rx_broadcast_pkts, m->rx_multicast_pkts, ++ m->rx_jabber_pkts, m->rx_oversize_pkts); ++ bcm_bprintf(b, "rx_fragment_pkts %d rx_missed_pkts %d rx_crc_align_errs %d " ++ "rx_undersize %d\n", ++ m->rx_fragment_pkts, m->rx_missed_pkts, ++ m->rx_crc_align_errs, m->rx_undersize); ++ bcm_bprintf(b, "rx_crc_errs %d rx_align_errs %d rx_symbol_errs %d\n", ++ m->rx_crc_errs, m->rx_align_errs, m->rx_symbol_errs); ++ bcm_bprintf(b, "rx_pause_pkts %d rx_nonpause_pkts %d\n", ++ m->rx_pause_pkts, m->rx_nonpause_pkts); ++} ++ ++static void ++chipenablepme(ch_t *ch) ++{ ++ return; ++} ++ ++static void ++chipdisablepme(ch_t *ch) ++{ ++ return; ++} ++ ++static void ++chipduplexupd(ch_t *ch) ++{ ++ uint32 cmdcfg; ++ int32 duplex, speed; ++#if (defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_HR3)) ++ uint32_t sdctl; ++#endif /* defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_HR3) */ ++ ++ cmdcfg = R_REG(ch->osh, &ch->regs->cmdcfg); ++ ++ /* check if duplex mode changed */ ++ if (ch->etc->duplex && (cmdcfg & CC_HD)) { ++ duplex = 0; ++ } else if (!ch->etc->duplex && ((cmdcfg & CC_HD) == 0)) { ++ duplex = CC_HD; ++ } else { ++ duplex = -1; ++ } ++ ++ /* check if the speed changed */ ++ speed = ((cmdcfg & CC_ES_MASK) >> CC_ES_SHIFT); ++ if ((ch->etc->speed == 1000) && (speed != 2)) { ++ speed = 2; ++ } else if ((ch->etc->speed == 100) && (speed != 1)) { ++ speed = 1; ++ } else if ((ch->etc->speed == 10) && (speed != 0)) { ++ speed = 0; ++ } else { ++ speed = -1; ++ } ++ ++ /* no duplex or speed change required */ ++ if ((speed == -1) && (duplex == -1)) { ++ return; ++ } ++ ++ /* update the speed */ ++ if (speed != -1) { ++ cmdcfg &= ~CC_ES_MASK; ++ cmdcfg |= (speed << CC_ES_SHIFT); ++ } ++ ++ /* update the duplex mode */ ++ if (duplex != -1) { ++ cmdcfg &= ~CC_HD; ++ cmdcfg |= duplex; ++ } ++ ++#if defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || \ ++ defined(CONFIG_MACH_SB2) || defined(CONFIG_MACH_GH2) ++ cmdcfg |= (CC_AE | CC_OT | CC_OR); ++#endif /* defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || \ ++ defined(CONFIG_MACH_SB2) || defined(CONFIG_MACH_GH2) */ ++ ++ ET_TRACE(("chipduplexupd: updating speed & duplex %x\n", cmdcfg)); ++ ++ /* put mac in reset */ ++ gmac_init_reset(ch); ++ ++ W_REG(ch->osh, &ch->regs->cmdcfg, cmdcfg); ++ ++ /* bring mac out of reset */ ++ gmac_clear_reset(ch); ++ ++#if (defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_HR3)) ++ sdctl = R_REG(ch->osh, &ch->regs->serdes_ctl); ++ sdctl &= ~(SC_FORCE_SPD_STRAP_MASK); ++ switch (ch->etc->speed) { ++ case 1000: ++ sdctl |= SC_FORCE_SPD_1G_VAL; ++ break; ++ case 100: ++ sdctl |= SC_FORCE_SPD_100M_VAL; ++ break; ++ default: ++ break; ++ } ++ W_REG(ch->osh, &ch->regs->serdes_ctl, sdctl); ++#endif /* (defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_HR3)) */ ++} ++ ++#ifdef CONFIG_SERDES_ASYMMETRIC_MODE ++static void ++chipforcespddpx(ch_t *ch) ++{ ++ uint32 cmdcfg; ++ int32 duplex=0, speed; ++ ++ cmdcfg = R_REG(ch->osh, &ch->regs->cmdcfg); ++ ++ /* set duplex */ ++ if (!ch->etc->duplex) ++ duplex = CC_HD; ++ ++ /* set speed */ ++ if (ch->etc->speed == 10) { ++ speed = 0; ++ } else if (ch->etc->speed == 100) { ++ speed = 1; ++ } else { ++ speed = 2; ++ } ++ ++ /* update the speed */ ++ cmdcfg &= ~CC_ES_MASK; ++ cmdcfg |= (speed << CC_ES_SHIFT); ++ ++ /* update the duplex mode */ ++ cmdcfg &= ~CC_HD; ++ cmdcfg |= duplex; ++ ++ ET_TRACE(("chipforcespddpx: forcing speed & duplex %x\n", cmdcfg)); ++ ++ /* put mac in reset */ ++ gmac_init_reset(ch); ++ ++ W_REG(ch->osh, &ch->regs->cmdcfg, cmdcfg); ++ ++ /* bring mac out of reset */ ++ gmac_clear_reset(ch); ++ ++ if (ch->etc->up) { ++ serdes_speeddpx_set(ch->etc->unit, ch->etc->int_phyaddr, ch->etc->speed, ch->etc->duplex); ++ } ++} ++#endif /* CONFIG_SERDES_ASYMMETRIC_MODE */ ++ ++ ++static uint16 ++chipphyrd(ch_t *ch, uint phyaddr, uint reg) ++{ ++ uint16 val = 0; ++ uint32 addr = PHY_REG_ADDR(phyaddr); ++ ++#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || defined(CONFIG_MACH_SB2)) ++ if (PHY_REG_BUS(phyaddr)) { /* Internal serdes */ ++ val = serdes_rd_reg(ch->etc->unit, addr, reg); ++ } else { ++ phy5461_rd_reg(ch->etc->unit, addr, ++ PHY_REG_FLAGS(phyaddr) ? SOC_PHY_REG_1000X : 0, ++ PHY_REG_BANK(phyaddr), reg, &val); ++ } ++#elif defined(CONFIG_MACH_HR2) ++ phy5221_rd_reg(ch->etc->unit, addr, PHY_REG_BANK(phyaddr), reg, &val); ++#elif defined(CONFIG_MACH_HR3) ++#if defined(CONFIG_MACH_WH2) ++ iproc_mii_read(MII_DEV_LOCAL, addr, reg, &val); ++#else ++ phy5481_rd_reg(ch->etc->unit, addr, PHY_REG_BANK(phyaddr), reg, &val); ++#endif ++#elif defined(CONFIG_MACH_GH) ++ phy5481_rd_reg(ch->etc->unit, addr, PHY_REG_BANK(phyaddr), reg, &val); ++#elif defined(CONFIG_MACH_GH2) ++ phy542xx_rd_reg(addr, PHY_REG_FLAGS(phyaddr), reg, &val); ++#endif /* defined(CONFIG_MACH_GH2) */ ++ ++ return val; ++} ++ ++static void ++chipphywr(ch_t *ch, uint phyaddr, uint reg, uint16 val) ++{ ++ uint32 addr = PHY_REG_ADDR(phyaddr); ++ ++#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || defined(CONFIG_MACH_SB2)) ++ if (PHY_REG_BUS(phyaddr)) { /* Internal serdes */ ++ serdes_wr_reg(ch->etc->unit, addr, reg, val); ++ } else { ++ phy5461_wr_reg(ch->etc->unit, addr, ++ PHY_REG_FLAGS(phyaddr) ? SOC_PHY_REG_1000X : 0, ++ PHY_REG_BANK(phyaddr), reg, &val); ++ } ++#elif defined(CONFIG_MACH_HR2) ++ phy5221_wr_reg(ch->etc->unit, addr, PHY_REG_BANK(phyaddr), reg, &val); ++#elif defined(CONFIG_MACH_HR3) ++#if defined(CONFIG_MACH_WH2) ++ iproc_mii_write(MII_DEV_LOCAL, addr, reg, val); ++#else ++ phy5481_wr_reg(ch->etc->unit, addr, PHY_REG_BANK(phyaddr), reg, &val); ++#endif ++#elif defined(CONFIG_MACH_GH) ++ phy5481_wr_reg(ch->etc->unit, addr, PHY_REG_BANK(phyaddr), reg, &val); ++#elif defined(CONFIG_MACH_GH2) ++ phy542xx_wr_reg(addr, PHY_REG_FLAGS(phyaddr), reg, val); ++#endif /* defined(CONFIG_MACH_GH2) */ ++} ++ ++static void ++chipphyor(ch_t *ch, uint phyaddr, uint reg, uint16 val) ++{ ++ uint16 tmp; ++ ++ tmp = chipphyrd(ch, phyaddr, reg); ++ tmp |= val; ++ chipphywr(ch, phyaddr, reg, tmp); ++} ++ ++static void ++chipphyreset(ch_t *ch) ++{ ++ uint ext_phyaddr = ch->etc->phyaddr; ++ uint int_phyaddr = ch->etc->int_phyaddr; ++ ++ ASSERT(ext_phyaddr < MAXEPHY); ++ if (ext_phyaddr == EPHY_NOREG) { ++ return; ++ } ++ ++ ET_TRACE(("et%d: chipphyreset, ext_phyaddr: 0x%x, int_phyaddr: 0x%x\n", ++ ch->etc->unit, ext_phyaddr, int_phyaddr)); ++ ++ chipphywr(ch, ext_phyaddr, 0, CTL_RESET); ++ OSL_DELAY(100); ++ if (chipphyrd(ch, ext_phyaddr, 0) & CTL_RESET) { ++ ET_ERROR(("et%d: chipphyreset: reset not complete\n", ch->etc->unit)); ++ } ++ ++ /* Internal serdes reset */ ++ if (int_phyaddr < MAXEPHY) { ++#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || defined(CONFIG_MACH_SB2)) ++ serdes_reset(ch->etc->unit, int_phyaddr); ++#elif defined(CONFIG_MACH_GH2) ++ sgmiiplus2_serdes_reset(ch->etc->unit, int_phyaddr); ++#elif defined(CONFIG_MACH_WH2) ++ if (select & 0x04) /* select Serdes (SGMII Plus2) path */ ++ sgmiiplus2_serdes_reset(ch->etc->unit, int_phyaddr); ++#endif ++ } ++ ++ chipphyinit(ch); ++} ++ ++static void ++chipphyinit(ch_t *ch) ++{ ++ uint ext_phyaddr = ch->etc->phyaddr; ++ uint int_phyaddr = ch->etc->int_phyaddr; ++ ++ ASSERT(ext_phyaddr < MAXEPHY); ++ if (ext_phyaddr == EPHY_NOREG) { ++ return; ++ } ++ ++ ET_TRACE(("et%d: chipphyinit, ext_phyaddr: 0x%x, int_phyaddr: 0x%x\n", ++ ch->etc->unit, ext_phyaddr, int_phyaddr)); ++ ++#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || defined(CONFIG_MACH_SB2)) ++ phy5461_init(ch->etc->unit, ext_phyaddr); ++#elif defined(CONFIG_MACH_HR2) ++ phy5221_init(ch->etc->unit, ext_phyaddr); ++#elif defined(CONFIG_MACH_GH) ++ phy5481_init(ch->etc->unit, ext_phyaddr); ++#elif defined(CONFIG_MACH_HR3) ++ ++#if defined(CONFIG_MACH_WH2) ++ if ((select & 0x04) == 0x0) /* select egphy28 path */ ++ { ++ void __iomem *base; ++ base = of_iomap(of_find_compatible_node(NULL, NULL, IPROC_CMICD_COMPATIBLE), 0); ++ egphy28_init(base, ext_phyaddr); ++ } ++#else ++ phy5481_init(ch->etc->unit, ext_phyaddr); ++#endif ++ ++#elif defined(CONFIG_MACH_GH2) ++ phy542xx_init(ext_phyaddr); ++#endif /* defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_HR3) */ ++ ++ /* Internal serdes reset */ ++ if (int_phyaddr < MAXEPHY) { ++#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || defined(CONFIG_MACH_SB2)) ++ serdes_init(ch->etc->unit, int_phyaddr); ++#elif defined(CONFIG_MACH_GH2) ++ sgmiiplus2_serdes_init(ch->etc->unit, int_phyaddr); ++#elif defined(CONFIG_MACH_WH2) ++ if (select & 0x04) /* select Serdes (SGMII Plus2) path */ ++ { ++ sgmiiplus2_serdes_init(ch->etc->unit, int_phyaddr); ++ } ++#endif ++ } ++} ++ ++static void ++chipphyforce(ch_t *ch, uint phyaddr) ++{ ++ etc_info_t *etc; ++ uint16 ctl; ++#ifdef CONFIG_FORCED_MODE_AUTO_MDIX ++ uint16 adv; ++#endif ++ ASSERT(phyaddr < MAXEPHY); ++ ++ if (phyaddr == EPHY_NOREG) { ++ return; ++ } ++ ++ etc = ch->etc; ++ ++ if (etc->forcespeed == ET_AUTO) { ++ return; ++ } ++ ++ ET_TRACE(("et%d: chipphyforce: phyaddr %d speed %d\n", ++ ch->etc->unit, phyaddr, etc->forcespeed)); ++ ++ ctl = chipphyrd(ch, phyaddr, PHY_MII_CTRLr_ADDR); ++ ctl &= ~(CTL_SPEED | CTL_SPEED_MSB | CTL_ANENAB | CTL_DUPLEX); ++#ifdef CONFIG_FORCED_MODE_AUTO_MDIX ++ adv = chipphyrd(ch, phyaddr, PHY_MII_GB_CTRLr_ADDR); ++ adv &= ~(ADV_1000FULL | ADV_1000HALF); ++ chipphywr(ch, phyaddr, PHY_MII_GB_CTRLr_ADDR, adv); ++ ++ adv = chipphyrd(ch, phyaddr, PHY_MII_ANAr_ADDR); ++ adv &= ~(ADV_100FULL | ADV_100HALF | ADV_10FULL | ADV_10HALF); ++#endif ++ switch (etc->forcespeed) { ++ case ET_10HALF: ++#ifdef CONFIG_FORCED_MODE_AUTO_MDIX ++ adv |= ADV_10HALF; ++#endif ++ break; ++ ++ case ET_10FULL: ++ ctl |= CTL_DUPLEX; ++#ifdef CONFIG_FORCED_MODE_AUTO_MDIX ++ adv |= ADV_10FULL; ++#endif ++ break; ++ ++ case ET_100HALF: ++ ctl |= CTL_SPEED_100; ++#ifdef CONFIG_FORCED_MODE_AUTO_MDIX ++ adv |= ADV_100HALF; ++#endif ++ break; ++ ++ case ET_100FULL: ++ ctl |= (CTL_SPEED_100 | CTL_DUPLEX); ++#ifdef CONFIG_FORCED_MODE_AUTO_MDIX ++ adv |= ADV_100FULL; ++#endif ++ break; ++ ++ case ET_1000FULL: ++ ctl |= (CTL_SPEED_1000 | CTL_DUPLEX); ++ break; ++ } ++ ++ chipphywr(ch, phyaddr, PHY_MII_CTRLr_ADDR, ctl); ++#ifdef CONFIG_FORCED_MODE_AUTO_MDIX ++ chipphywr(ch, phyaddr, PHY_MII_ANAr_ADDR, adv); ++ if (etc->forcespeed != ET_1000FULL) { ++#if defined(CONFIG_MACH_GH2) ++ phy542xx_force_auto_mdix(phyaddr, 0); ++#else ++ adv = chipphyrd(ch, phyaddr | (PHY_MII_MISC_CTRLr_BANK << 8), PHY_MII_MISC_CTRLr_ADDR); ++ adv |= MII_FORCED_AUTO_MDIX; ++ chipphywr(ch, phyaddr | (PHY_MII_MISC_CTRLr_BANK << 8), PHY_MII_MISC_CTRLr_ADDR, adv); ++#endif /* defined(CONFIG_MACH_GH2) */ ++ } ++#endif ++} ++ ++/* set selected capability bits in autonegotiation advertisement */ ++static void ++chipphyadvertise(ch_t *ch, uint phyaddr) ++{ ++ etc_info_t *etc; ++ uint16 adv, adv2; ++ ++ ASSERT(phyaddr < MAXEPHY); ++ ++ if (phyaddr == EPHY_NOREG) { ++ return; ++ } ++ ++ etc = ch->etc; ++ ++ if ((etc->forcespeed != ET_AUTO) || !etc->needautoneg) { ++ return; ++ } ++ ++ ASSERT(etc->advertise); ++ ++ ET_TRACE(("et%d: chipphyadvertise: phyaddr %d advertise %x\n", ++ ch->etc->unit, phyaddr, etc->advertise)); ++ ++ /* reset our advertised capabilitity bits */ ++ adv = chipphyrd(ch, phyaddr, PHY_MII_ANAr_ADDR); ++ adv &= ~(ADV_100FULL | ADV_100HALF | ADV_10FULL | ADV_10HALF); ++ adv |= (etc->advertise | ADV_PAUSE); ++ chipphywr(ch, phyaddr, PHY_MII_ANAr_ADDR, adv); ++ ++ adv2 = chipphyrd(ch, phyaddr, PHY_MII_GB_CTRLr_ADDR); ++ adv2 &= ~(ADV_1000FULL | ADV_1000HALF); ++ adv2 |= etc->advertise2; ++ chipphywr(ch, phyaddr, PHY_MII_GB_CTRLr_ADDR, adv2); ++ ++ ET_TRACE(("et%d: chipphyadvertise: phyaddr %d adv %x adv2 %x phyad0 %x\n", ++ ch->etc->unit, phyaddr, adv, adv2, chipphyrd(ch, phyaddr, 0))); ++#ifdef CONFIG_FORCED_MODE_AUTO_MDIX ++#if defined(CONFIG_MACH_GH2) ++ phy542xx_force_auto_mdix(phyaddr, 0); ++#else ++ adv = chipphyrd(ch, phyaddr | (PHY_MII_MISC_CTRLr_BANK << 8), PHY_MII_MISC_CTRLr_ADDR); ++ if (adv & MII_FORCED_AUTO_MDIX) { ++ adv &= ~MII_FORCED_AUTO_MDIX; ++ chipphywr(ch, phyaddr | (PHY_MII_MISC_CTRLr_BANK << 8), PHY_MII_MISC_CTRLr_ADDR, adv); ++ } ++#endif /* defined(CONFIG_MACH_GH2) */ ++#endif ++ /* restart autonegotiation */ ++ chipphyor(ch, phyaddr, PHY_MII_CTRLr_ADDR, CTL_RESTART); ++ etc->needautoneg = FALSE; ++} ++ ++static void ++chipphyenable(ch_t *ch, uint eth_num, uint phyaddr, int enable) ++{ ++#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || defined(CONFIG_MACH_SB2)) ++ phy5461_enable_set(eth_num, phyaddr, enable); ++#elif defined(CONFIG_MACH_HR2) ++ phy5221_enable_set(eth_num, phyaddr, enable); ++#elif defined(CONFIG_MACH_GH) ++ phy5481_enable_set(eth_num, phyaddr, enable); ++#elif defined(CONFIG_MACH_HR3) ++#if defined(CONFIG_MACH_WH2) ++ if ((select & 0x04) == 0x0) /* Select EGPHY28 path */ ++ egphy28_enable_set(phyaddr, enable); ++#else ++ phy5481_enable_set(eth_num, phyaddr, enable); ++#endif ++#elif defined(CONFIG_MACH_GH2) ++ phy542xx_enable_set(phyaddr, enable); ++#endif /* defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || defined(CONFIG_MACH_SB2) */ ++} ++ ++#ifdef GMAC_RATE_LIMITING ++void ++etc_check_rate_limiting(etc_info_t *etc, void *pch) ++{ ++ /*ch_t *ch = (ch_t*)pch;*/ ++ uint32 timediff, unit; ++ int bc_cnt_diff; ++ static uint32 first_run[2]={1,1}; ++ static uint32 prev_bc_frame_cnt[2]={0,0}, bc_frame_cnt[2]={0,0}; ++ ++ unit = etc->unit; ++ if (first_run[unit]) { ++ bc_frame_cnt[unit] = etc->rx_bc_frame_cnt; ++ prev_bc_frame_cnt[unit] = bc_frame_cnt[unit]; ++ first_run[unit] = 0; ++ } ++ else { ++ bc_cnt_diff = etc->rx_bc_frame_cnt - prev_bc_frame_cnt[unit]; ++ if (bc_cnt_diff >= 0) ++ bc_frame_cnt[unit] += bc_cnt_diff; ++ else ++ bc_frame_cnt[unit] += (bc_cnt_diff + 0xffffffff + 0x1); ++ prev_bc_frame_cnt[unit] = etc->rx_bc_frame_cnt; ++ } ++ ++ timediff = ((long)jiffies - (long)(etc->rl_prior_jiffies)); ++ if ((timediff >> 5) != 0) { ++ /* ++ * 32 or more jiffies have gone by, See if ++ * we're seeing too many broadcast packets. ++ */ ++ if ((timediff >> 5) == 1) { ++ /* 32-63 jiffies elapsed */ ++ if (((bc_frame_cnt[unit] >> 10) != 0) && ++ !(etc->rl_stopping_broadcasts)) { ++ /* 1K or more broadcast packets have arrived in ++ * 32-63 jiffies; try to throttle back the ++ * incoming packets ++ */ ++ etc->rl_stopping_broadcasts = 1; ++ printk("et%d: %s: stopping broadcasts bc_frame_cnts(0x%x)\n", ++ etc->unit, __FUNCTION__, bc_frame_cnt[unit]); ++ if (!timer_pending(&etc->rl_timer)) { ++ etc->rl_timer.expires = jiffies + HZ; ++ add_timer(&etc->rl_timer); ++ etc->rl_set=TRUE; ++ } ++ } ++ } ++ etc->rl_prior_jiffies = jiffies; ++ bc_frame_cnt[unit] = 0; ++ } ++} ++#endif /* GMAC_RATE_LIMITING */ ++ ++ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/et/sys/etcgmac.h b/drivers/net/ethernet/broadcom/gmac/src/et/sys/etcgmac.h +--- a/drivers/net/ethernet/broadcom/gmac/src/et/sys/etcgmac.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/et/sys/etcgmac.h 2017-11-09 17:53:43.905290000 +0800 +@@ -0,0 +1,65 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ * ++ * Broadcom Gigabit Ethernet MAC defines. ++ * ++ * $Id: etcgmac.h 267700 2011-06-19 15:41:07Z sudhirbs $ ++ */ ++ ++#ifndef _ETCGMAC_H_ ++#define _ETCGMAC_H_ ++ ++#if (defined(CONFIG_MACH_HR2) || defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_HR3)) ++#define IPROC_NUM_GMACS 1 ++#else ++#define IPROC_NUM_GMACS 2 ++#endif ++ ++/* chip interrupt bit error summary */ ++#define I_ERRORS (I_PDEE | I_PDE | I_DE | I_RDU | I_RFO | I_XFU) ++#define DEF_INTMASK (I_XI0 | I_XI1 | I_XI2 | I_XI3 | I_RI | I_ERRORS) ++ ++#define GMAC_RESET_DELAY 2 ++ ++#define GMAC_MIN_FRAMESIZE 17 /* gmac can only send frames of ++ * size above 17 octetes. ++ */ ++ ++#define LOOPBACK_MODE_DMA 0 /* loopback the packet at the DMA engine */ ++#define LOOPBACK_MODE_MAC 1 /* loopback the packet at MAC */ ++#define LOOPBACK_MODE_NONE 2 /* no Loopback */ ++ ++#define FA2_GMAC_MAX_LEN 2048 ++ ++#define DMAREG(ch, dir, qnum) ((dir == DMA_TX) ? \ ++ (void *)(uintptr)&(ch->regs->dmaregs[qnum].dmaxmt) : \ ++ (void *)(uintptr)&(ch->regs->dmaregs[qnum].dmarcv)) ++ ++/* ++ * Add multicast address to the list. Multicast address are maintained as ++ * hash table with chaining. ++ */ ++typedef struct mclist { ++ struct ether_addr mc_addr; /* multicast address to allow */ ++ struct mclist *next; /* next entry */ ++} mflist_t; ++ ++#define GMAC_HASHT_SIZE 16 /* hash table size */ ++#define GMAC_MCADDR_HASH(m) ((((uint8 *)(m))[3] + ((uint8 *)(m))[4] + \ ++ ((uint8 *)(m))[5]) & (GMAC_HASHT_SIZE - 1)) ++ ++#define ETHER_MCADDR_CMP(x, y) ((((uint16 *)(x))[0] ^ ((uint16 *)(y))[0]) | \ ++ (((uint16 *)(x))[1] ^ ((uint16 *)(y))[1]) | \ ++ (((uint16 *)(x))[2] ^ ((uint16 *)(y))[2])) ++ ++#define SUCCESS 0 ++#define FAILURE -1 ++ ++typedef struct mcfilter { ++ /* hash table for multicast filtering */ ++ mflist_t *bucket[GMAC_HASHT_SIZE]; ++} mcfilter_t; ++ ++extern uint32 find_priq(uint32 pri_map); ++ ++#endif /* _ETCGMAC_H_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/Makefile b/drivers/net/ethernet/broadcom/gmac/src/include/Makefile +--- a/drivers/net/ethernet/broadcom/gmac/src/include/Makefile 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/Makefile 2017-11-09 17:53:43.912294000 +0800 +@@ -0,0 +1,62 @@ ++# This script serves following purpose: ++# ++# 1. It generates native version information by querying ++# automerger maintained database to see where src/include ++# came from ++# 2. For select components, as listed in compvers.sh ++# it generates component version files ++# ++# Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++# ++# Permission to use, copy, modify, and/or distribute this software for any ++# purpose with or without fee is hereby granted, provided that the above ++# copyright notice and this permission notice appear in all copies. ++# ++# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++# ++# ++ ++SRCBASE := .. ++ ++TARGETS := epivers.h ++ ++ifdef VERBOSE ++export VERBOSE ++endif ++ ++all release: epivers compvers ++ ++# Generate epivers.h for native branch version ++epivers: ++ bash epivers.sh ++ ++# Generate epivers.h for native branch version ++compvers: ++ @if [ -s "compvers.sh" ]; then \ ++ echo "Generating component versions, if any"; \ ++ bash compvers.sh; \ ++ else \ ++ echo "Skipping component version generation"; \ ++ fi ++ ++# Generate epivers.h for native branch version ++clean_compvers: ++ @if [ -s "compvers.sh" ]; then \ ++ echo "bash compvers.sh clean"; \ ++ bash compvers.sh clean; \ ++ else \ ++ echo "Skipping component version clean"; \ ++ fi ++ ++clean: ++ rm -f $(TARGETS) *.prev ++ ++clean_all: clean clean_compvers ++ ++.PHONY: all release clean epivers compvers clean_compvers +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/aidmp.h b/drivers/net/ethernet/broadcom/gmac/src/include/aidmp.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/aidmp.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/aidmp.h 2017-11-09 17:53:43.913291000 +0800 +@@ -0,0 +1,383 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Broadcom AMBA Interconnect definitions. ++ * ++ * $Id: aidmp.h 241182 2011-02-17 21:50:03Z $ ++ */ ++ ++#ifndef _AIDMP_H ++#define _AIDMP_H ++ ++/* Manufacturer Ids */ ++#define MFGID_ARM 0x43b ++#define MFGID_BRCM 0x4bf ++#define MFGID_MIPS 0x4a7 ++ ++/* Component Classes */ ++#define CC_SIM 0 ++#define CC_EROM 1 ++#define CC_CORESIGHT 9 ++#define CC_VERIF 0xb ++#define CC_OPTIMO 0xd ++#define CC_GEN 0xe ++#define CC_PRIMECELL 0xf ++ ++/* Enumeration ROM registers */ ++#define ER_EROMENTRY 0x000 ++#define ER_REMAPCONTROL 0xe00 ++#define ER_REMAPSELECT 0xe04 ++#define ER_MASTERSELECT 0xe10 ++#define ER_ITCR 0xf00 ++#define ER_ITIP 0xf04 ++ ++/* Erom entries */ ++#define ER_TAG 0xe ++#define ER_TAG1 0x6 ++#define ER_VALID 1 ++#define ER_CI 0 ++#define ER_MP 2 ++#define ER_ADD 4 ++#define ER_END 0xe ++#define ER_BAD 0xffffffff ++ ++/* EROM CompIdentA */ ++#define CIA_MFG_MASK 0xfff00000 ++#define CIA_MFG_SHIFT 20 ++#define CIA_CID_MASK 0x000fff00 ++#define CIA_CID_SHIFT 8 ++#define CIA_CCL_MASK 0x000000f0 ++#define CIA_CCL_SHIFT 4 ++ ++/* EROM CompIdentB */ ++#define CIB_REV_MASK 0xff000000 ++#define CIB_REV_SHIFT 24 ++#define CIB_NSW_MASK 0x00f80000 ++#define CIB_NSW_SHIFT 19 ++#define CIB_NMW_MASK 0x0007c000 ++#define CIB_NMW_SHIFT 14 ++#define CIB_NSP_MASK 0x00003e00 ++#define CIB_NSP_SHIFT 9 ++#define CIB_NMP_MASK 0x000001f0 ++#define CIB_NMP_SHIFT 4 ++ ++/* EROM MasterPortDesc */ ++#define MPD_MUI_MASK 0x0000ff00 ++#define MPD_MUI_SHIFT 8 ++#define MPD_MP_MASK 0x000000f0 ++#define MPD_MP_SHIFT 4 ++ ++/* EROM AddrDesc */ ++#define AD_ADDR_MASK 0xfffff000 ++#define AD_SP_MASK 0x00000f00 ++#define AD_SP_SHIFT 8 ++#define AD_ST_MASK 0x000000c0 ++#define AD_ST_SHIFT 6 ++#define AD_ST_SLAVE 0x00000000 ++#define AD_ST_BRIDGE 0x00000040 ++#define AD_ST_SWRAP 0x00000080 ++#define AD_ST_MWRAP 0x000000c0 ++#define AD_SZ_MASK 0x00000030 ++#define AD_SZ_SHIFT 4 ++#define AD_SZ_4K 0x00000000 ++#define AD_SZ_8K 0x00000010 ++#define AD_SZ_16K 0x00000020 ++#define AD_SZ_SZD 0x00000030 ++#define AD_AG32 0x00000008 ++#define AD_ADDR_ALIGN 0x00000fff ++#define AD_SZ_BASE 0x00001000 /* 4KB */ ++ ++/* EROM SizeDesc */ ++#define SD_SZ_MASK 0xfffff000 ++#define SD_SG32 0x00000008 ++#define SD_SZ_ALIGN 0x00000fff ++ ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++typedef volatile struct _aidmp { ++ uint32 oobselina30; /* 0x000 */ ++ uint32 oobselina74; /* 0x004 */ ++ uint32 PAD[6]; ++ uint32 oobselinb30; /* 0x020 */ ++ uint32 oobselinb74; /* 0x024 */ ++ uint32 PAD[6]; ++ uint32 oobselinc30; /* 0x040 */ ++ uint32 oobselinc74; /* 0x044 */ ++ uint32 PAD[6]; ++ uint32 oobselind30; /* 0x060 */ ++ uint32 oobselind74; /* 0x064 */ ++ uint32 PAD[38]; ++ uint32 oobselouta30; /* 0x100 */ ++ uint32 oobselouta74; /* 0x104 */ ++ uint32 PAD[6]; ++ uint32 oobseloutb30; /* 0x120 */ ++ uint32 oobseloutb74; /* 0x124 */ ++ uint32 PAD[6]; ++ uint32 oobseloutc30; /* 0x140 */ ++ uint32 oobseloutc74; /* 0x144 */ ++ uint32 PAD[6]; ++ uint32 oobseloutd30; /* 0x160 */ ++ uint32 oobseloutd74; /* 0x164 */ ++ uint32 PAD[38]; ++ uint32 oobsynca; /* 0x200 */ ++ uint32 oobseloutaen; /* 0x204 */ ++ uint32 PAD[6]; ++ uint32 oobsyncb; /* 0x220 */ ++ uint32 oobseloutben; /* 0x224 */ ++ uint32 PAD[6]; ++ uint32 oobsyncc; /* 0x240 */ ++ uint32 oobseloutcen; /* 0x244 */ ++ uint32 PAD[6]; ++ uint32 oobsyncd; /* 0x260 */ ++ uint32 oobseloutden; /* 0x264 */ ++ uint32 PAD[38]; ++ uint32 oobaextwidth; /* 0x300 */ ++ uint32 oobainwidth; /* 0x304 */ ++ uint32 oobaoutwidth; /* 0x308 */ ++ uint32 PAD[5]; ++ uint32 oobbextwidth; /* 0x320 */ ++ uint32 oobbinwidth; /* 0x324 */ ++ uint32 oobboutwidth; /* 0x328 */ ++ uint32 PAD[5]; ++ uint32 oobcextwidth; /* 0x340 */ ++ uint32 oobcinwidth; /* 0x344 */ ++ uint32 oobcoutwidth; /* 0x348 */ ++ uint32 PAD[5]; ++ uint32 oobdextwidth; /* 0x360 */ ++ uint32 oobdinwidth; /* 0x364 */ ++ uint32 oobdoutwidth; /* 0x368 */ ++ uint32 PAD[37]; ++ uint32 ioctrlset; /* 0x400 */ ++ uint32 ioctrlclear; /* 0x404 */ ++ uint32 ioctrl; /* 0x408 */ ++ uint32 PAD[61]; ++ uint32 iostatus; /* 0x500 */ ++ uint32 PAD[127]; ++ uint32 ioctrlwidth; /* 0x700 */ ++ uint32 iostatuswidth; /* 0x704 */ ++ uint32 PAD[62]; ++ uint32 resetctrl; /* 0x800 */ ++ uint32 resetstatus; /* 0x804 */ ++ uint32 resetreadid; /* 0x808 */ ++ uint32 resetwriteid; /* 0x80c */ ++ uint32 PAD[60]; ++ uint32 errlogctrl; /* 0x900 */ ++ uint32 errlogdone; /* 0x904 */ ++ uint32 errlogstatus; /* 0x908 */ ++ uint32 errlogaddrlo; /* 0x90c */ ++ uint32 errlogaddrhi; /* 0x910 */ ++ uint32 errlogid; /* 0x914 */ ++ uint32 errloguser; /* 0x918 */ ++ uint32 errlogflags; /* 0x91c */ ++ uint32 PAD[56]; ++ uint32 intstatus; /* 0xa00 */ ++ uint32 PAD[255]; ++ uint32 config; /* 0xe00 */ ++ uint32 PAD[63]; ++ uint32 itcr; /* 0xf00 */ ++ uint32 PAD[3]; ++ uint32 itipooba; /* 0xf10 */ ++ uint32 itipoobb; /* 0xf14 */ ++ uint32 itipoobc; /* 0xf18 */ ++ uint32 itipoobd; /* 0xf1c */ ++ uint32 PAD[4]; ++ uint32 itipoobaout; /* 0xf30 */ ++ uint32 itipoobbout; /* 0xf34 */ ++ uint32 itipoobcout; /* 0xf38 */ ++ uint32 itipoobdout; /* 0xf3c */ ++ uint32 PAD[4]; ++ uint32 itopooba; /* 0xf50 */ ++ uint32 itopoobb; /* 0xf54 */ ++ uint32 itopoobc; /* 0xf58 */ ++ uint32 itopoobd; /* 0xf5c */ ++ uint32 PAD[4]; ++ uint32 itopoobain; /* 0xf70 */ ++ uint32 itopoobbin; /* 0xf74 */ ++ uint32 itopoobcin; /* 0xf78 */ ++ uint32 itopoobdin; /* 0xf7c */ ++ uint32 PAD[4]; ++ uint32 itopreset; /* 0xf90 */ ++ uint32 PAD[15]; ++ uint32 peripherialid4; /* 0xfd0 */ ++ uint32 peripherialid5; /* 0xfd4 */ ++ uint32 peripherialid6; /* 0xfd8 */ ++ uint32 peripherialid7; /* 0xfdc */ ++ uint32 peripherialid0; /* 0xfe0 */ ++ uint32 peripherialid1; /* 0xfe4 */ ++ uint32 peripherialid2; /* 0xfe8 */ ++ uint32 peripherialid3; /* 0xfec */ ++ uint32 componentid0; /* 0xff0 */ ++ uint32 componentid1; /* 0xff4 */ ++ uint32 componentid2; /* 0xff8 */ ++ uint32 componentid3; /* 0xffc */ ++} aidmp_t; ++ ++#endif /* _LANGUAGE_ASSEMBLY */ ++ ++/* Out-of-band Router registers */ ++#define OOB_BUSCONFIG 0x020 ++#define OOB_STATUSA 0x100 ++#define OOB_STATUSB 0x104 ++#define OOB_STATUSC 0x108 ++#define OOB_STATUSD 0x10c ++#define OOB_ENABLEA0 0x200 ++#define OOB_ENABLEA1 0x204 ++#define OOB_ENABLEA2 0x208 ++#define OOB_ENABLEA3 0x20c ++#define OOB_ENABLEB0 0x280 ++#define OOB_ENABLEB1 0x284 ++#define OOB_ENABLEB2 0x288 ++#define OOB_ENABLEB3 0x28c ++#define OOB_ENABLEC0 0x300 ++#define OOB_ENABLEC1 0x304 ++#define OOB_ENABLEC2 0x308 ++#define OOB_ENABLEC3 0x30c ++#define OOB_ENABLED0 0x380 ++#define OOB_ENABLED1 0x384 ++#define OOB_ENABLED2 0x388 ++#define OOB_ENABLED3 0x38c ++#define OOB_ITCR 0xf00 ++#define OOB_ITIPOOBA 0xf10 ++#define OOB_ITIPOOBB 0xf14 ++#define OOB_ITIPOOBC 0xf18 ++#define OOB_ITIPOOBD 0xf1c ++#define OOB_ITOPOOBA 0xf30 ++#define OOB_ITOPOOBB 0xf34 ++#define OOB_ITOPOOBC 0xf38 ++#define OOB_ITOPOOBD 0xf3c ++ ++/* DMP wrapper registers */ ++#define AI_OOBSELINA30 0x000 ++#define AI_OOBSELINA74 0x004 ++#define AI_OOBSELINB30 0x020 ++#define AI_OOBSELINB74 0x024 ++#define AI_OOBSELINC30 0x040 ++#define AI_OOBSELINC74 0x044 ++#define AI_OOBSELIND30 0x060 ++#define AI_OOBSELIND74 0x064 ++#define AI_OOBSELOUTA30 0x100 ++#define AI_OOBSELOUTA74 0x104 ++#define AI_OOBSELOUTB30 0x120 ++#define AI_OOBSELOUTB74 0x124 ++#define AI_OOBSELOUTC30 0x140 ++#define AI_OOBSELOUTC74 0x144 ++#define AI_OOBSELOUTD30 0x160 ++#define AI_OOBSELOUTD74 0x164 ++#define AI_OOBSYNCA 0x200 ++#define AI_OOBSELOUTAEN 0x204 ++#define AI_OOBSYNCB 0x220 ++#define AI_OOBSELOUTBEN 0x224 ++#define AI_OOBSYNCC 0x240 ++#define AI_OOBSELOUTCEN 0x244 ++#define AI_OOBSYNCD 0x260 ++#define AI_OOBSELOUTDEN 0x264 ++#define AI_OOBAEXTWIDTH 0x300 ++#define AI_OOBAINWIDTH 0x304 ++#define AI_OOBAOUTWIDTH 0x308 ++#define AI_OOBBEXTWIDTH 0x320 ++#define AI_OOBBINWIDTH 0x324 ++#define AI_OOBBOUTWIDTH 0x328 ++#define AI_OOBCEXTWIDTH 0x340 ++#define AI_OOBCINWIDTH 0x344 ++#define AI_OOBCOUTWIDTH 0x348 ++#define AI_OOBDEXTWIDTH 0x360 ++#define AI_OOBDINWIDTH 0x364 ++#define AI_OOBDOUTWIDTH 0x368 ++ ++#if defined(IL_BIGENDIAN) && defined(BCMHND74K) ++/* Selective swapped defines for those registers we need in ++ * big-endian code. ++ */ ++#define AI_IOCTRLSET 0x404 ++#define AI_IOCTRLCLEAR 0x400 ++#define AI_IOCTRL 0x40c ++#define AI_IOSTATUS 0x504 ++#define AI_RESETCTRL 0x804 ++#define AI_RESETSTATUS 0x800 ++ ++#else /* !IL_BIGENDIAN || !BCMHND74K */ ++ ++#define AI_IOCTRLSET 0x400 ++#define AI_IOCTRLCLEAR 0x404 ++#define AI_IOCTRL 0x408 ++#define AI_IOSTATUS 0x500 ++#define AI_RESETCTRL 0x800 ++#define AI_RESETSTATUS 0x804 ++ ++#endif /* IL_BIGENDIAN && BCMHND74K */ ++ ++#define AI_IOCTRLWIDTH 0x700 ++#define AI_IOSTATUSWIDTH 0x704 ++ ++#define AI_RESETREADID 0x808 ++#define AI_RESETWRITEID 0x80c ++#define AI_ERRLOGCTRL 0xa00 ++#define AI_ERRLOGDONE 0xa04 ++#define AI_ERRLOGSTATUS 0xa08 ++#define AI_ERRLOGADDRLO 0xa0c ++#define AI_ERRLOGADDRHI 0xa10 ++#define AI_ERRLOGID 0xa14 ++#define AI_ERRLOGUSER 0xa18 ++#define AI_ERRLOGFLAGS 0xa1c ++#define AI_INTSTATUS 0xa00 ++#define AI_CONFIG 0xe00 ++#define AI_ITCR 0xf00 ++#define AI_ITIPOOBA 0xf10 ++#define AI_ITIPOOBB 0xf14 ++#define AI_ITIPOOBC 0xf18 ++#define AI_ITIPOOBD 0xf1c ++#define AI_ITIPOOBAOUT 0xf30 ++#define AI_ITIPOOBBOUT 0xf34 ++#define AI_ITIPOOBCOUT 0xf38 ++#define AI_ITIPOOBDOUT 0xf3c ++#define AI_ITOPOOBA 0xf50 ++#define AI_ITOPOOBB 0xf54 ++#define AI_ITOPOOBC 0xf58 ++#define AI_ITOPOOBD 0xf5c ++#define AI_ITOPOOBAIN 0xf70 ++#define AI_ITOPOOBBIN 0xf74 ++#define AI_ITOPOOBCIN 0xf78 ++#define AI_ITOPOOBDIN 0xf7c ++#define AI_ITOPRESET 0xf90 ++#define AI_PERIPHERIALID4 0xfd0 ++#define AI_PERIPHERIALID5 0xfd4 ++#define AI_PERIPHERIALID6 0xfd8 ++#define AI_PERIPHERIALID7 0xfdc ++#define AI_PERIPHERIALID0 0xfe0 ++#define AI_PERIPHERIALID1 0xfe4 ++#define AI_PERIPHERIALID2 0xfe8 ++#define AI_PERIPHERIALID3 0xfec ++#define AI_COMPONENTID0 0xff0 ++#define AI_COMPONENTID1 0xff4 ++#define AI_COMPONENTID2 0xff8 ++#define AI_COMPONENTID3 0xffc ++ ++/* resetctrl */ ++#define AIRC_RESET 1 ++ ++/* config */ ++#define AICFG_OOB 0x00000020 ++#define AICFG_IOS 0x00000010 ++#define AICFG_IOC 0x00000008 ++#define AICFG_TO 0x00000004 ++#define AICFG_ERRL 0x00000002 ++#define AICFG_RST 0x00000001 ++ ++/* bit defines for AI_OOBSELOUTB74 reg */ ++#define OOB_SEL_OUTEN_B_5 15 ++#define OOB_SEL_OUTEN_B_6 23 ++ ++#endif /* _AIDMP_H */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/arminc.h b/drivers/net/ethernet/broadcom/gmac/src/include/arminc.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/arminc.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/arminc.h 2017-11-09 17:53:43.914306000 +0800 +@@ -0,0 +1,317 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * HND Run Time Environment for standalone ARM programs. ++ * ++ * $Id: arminc.h 325951 2012-04-05 06:03:27Z $ ++ */ ++ ++#ifndef _ARMINC_H ++#define _ARMINC_H ++ ++ ++/* ARM defines */ ++ ++#ifdef _LANGUAGE_ASSEMBLY ++ ++/* ++ * LEAF - declare leaf routine ++ */ ++#define LEAF(function) \ ++ .section .text.function, "ax"; \ ++ .global function; \ ++ .func function; \ ++function: ++ ++#define THUMBLEAF(function) \ ++ .section .text.function, "ax"; \ ++ .global function; \ ++ .func function; \ ++ .thumb; \ ++ .thumb_func; \ ++function: ++ ++/* ++ * END - mark end of function ++ */ ++#define END(function) \ ++ .ltorg; \ ++ .endfunc; \ ++ .size function, . - function ++ ++#define DW(var, val) \ ++ .global var; \ ++ .type var, %object; \ ++ .size var, 4; \ ++ .align 2; \ ++var: .word val ++ ++ ++#define _ULCAST_ ++ ++#else ++ ++/* ++ * The following macros are especially useful for __asm__ ++ * inline assembler. ++ */ ++#ifndef __STR ++#define __STR(x) #x ++#endif ++#ifndef STR ++#define STR(x) __STR(x) ++#endif ++ ++#define _ULCAST_ (unsigned long) ++ ++#endif /* _LANGUAGE_ASSEMBLY */ ++ ++ ++#if defined(__ARM_ARCH_7M__) /* Cortex-M3 */ ++ ++/* Data Watchpoint and Trigger */ ++#define CM3_DWT_CTRL 0xe0001000 ++#define CM3_DWT_CYCCNT 0xe0001004 ++#define CM3_DWT_CPICNT 0xe0001008 ++#define CM3_DWT_EXCCNT 0xe000100c ++#define CM3_DWT_SLEEPCNT 0xe0001010 ++#define CM3_DWT_LSUCNT 0xe0001014 ++#define CM3_DWT_FOLDCNT 0xe0001018 ++#define CM3_DWT_COMP0 0xe0001020 ++#define CM3_DWT_MASK0 0xe0001024 ++#define CM3_DWT_FUNCTION0 0xe0001028 ++#define CM3_DWT_COMP1 0xe0001030 ++#define CM3_DWT_MASK1 0xe0001034 ++#define CM3_DWT_FUNCTION1 0xe0001038 ++#define CM3_DWT_COMP2 0xe0001040 ++#define CM3_DWT_MASK2 0xe0001044 ++#define CM3_DWT_FUNCTION2 0xe0001048 ++#define CM3_DWT_COMP3 0xe0001050 ++#define CM3_DWT_MASK3 0xe0001054 ++#define CM3_DWT_FUNCTION3 0xe0001058 ++ ++#define CM3_DWT_FUNCTION_DISAB 0 ++#define CM3_DWT_FUNCTION_WP_PCMATCH 4 ++#define CM3_DWT_FUNCTION_WP_READ 5 ++#define CM3_DWT_FUNCTION_WP_WRITE 6 ++#define CM3_DWT_FUNCTION_WP_RDWR 7 ++ ++#define CM3_NVIC_IC_TYPE 0xe000e004 /* Interrupt Control Type Reg */ ++#define CM3_NVIC_TICK_CSR 0xe000e010 /* SysTick Control and Status Reg */ ++#define CM3_NVIC_TICK_CSR_COUNTFLAG 0x10000 ++#define CM3_NVIC_TICK_CSR_CLKSOURCE 0x4 /* Set for core clock, 0 for ext ref */ ++#define CM3_NVIC_TICK_CSR_TICKINT 0x2 /* Set for intr on count going 1 => 0 */ ++#define CM3_NVIC_TICK_CSR_ENABLE 0x1 ++#define CM3_NVIC_TICK_RLDVAL 0xe000e014 /* SysTick Reload Value Reg */ ++#define CM3_NVIC_TICK_CURVAL 0xe000e018 /* SysTick Current Value Reg */ ++#define CM3_NVIC_TICK_CALVAL 0xe000e01c /* SysTick Calibration Value Reg */ ++ ++/* Interrupt enable/disable register */ ++#define CM3_NVIC_IRQ_SET_EN0 0xe000e100 /* Irq 0 to 31 Set Enable Reg */ ++#define CM3_NVIC_IRQ_SET_EN(n) (0xe000e100 + (n) * 4) /* Irq 0-31, 32-63, ..., 224-239 */ ++ ++#define CM3_NVIC_IRQ_CLR_EN0 0xe000e180 /* Irq 0 to 31 Clear Enable Reg [...] */ ++#define CM3_NVIC_IRQ_CLR_EN(n) (0xe000e180 + (n) * 4) /* Irq 0-31, 32-63, ..., 224-239 */ ++ ++#define CM3_NVIC_IRQ_SET_PND0 0xe000e200 /* Irq 0 to 31 Set Pending Reg [...] */ ++#define CM3_NVIC_IRQ_SET_PND(n) (0xe000e200 + (n) * 4) /* Irq 0-31, 32-63, ..., 224-239 */ ++ ++#define CM3_NVIC_IRQ_CLR_PND0 0xe000e280 /* Irq 0 to 31 Clear Pending Reg [...] */ ++#define CM3_NVIC_IRQ_CLR_PND(n) (0xe000e280 + (n) * 4) /* Irq 0-31, 32-63, ..., 224-239 */ ++ ++#define CM3_NVIC_IRQ_ACT_BIT0 0xe000e300 /* Irq 0 to 31 Active Bit Reg [...] */ ++#define CM3_NVIC_IRQ_ACT_BIT(n) (0xe000e300 + (n) * 4) /* Irq 0-31, 32-63, ..., 224-239 */ ++ ++#define CM3_NVIC_IRQ_PRIO0 0xe000e400 /* Irq 0 to 31 Priority Reg [...] */ ++#define CM3_NVIC_IRQ_PRIO(n) (0xe000e400 + (n) * 4) /* Irq 0-31, 32-63, ..., 224-239 */ ++ ++/* CPU control */ ++#define CM3_CPUID 0xe000ed00 ++#define CM3_INTCTLSTATE 0xe000ed04 ++#define CM3_VTOFF 0xe000ed08 /* Vector Table Offset */ ++#define CM3_SYSCTRL 0xe000ed10 ++#define CM3_CFGCTRL 0xe000ed14 ++#define CM3_CFGCTRL_UNALIGN_TRP 0x8 ++#define CM3_CFGCTRL_DIV_0_TRP 0x10 ++#define CM3_CFGCTRL_STKALIGN 0x200 ++ ++#define CM3_PFR0 0xe000ed40 ++#define CM3_PFR1 0xe000ed44 ++#define CM3_DFR0 0xe000ed48 ++#define CM3_AFR0 0xe000ed4c ++#define CM3_MMFR0 0xe000ed50 ++#define CM3_MMFR1 0xe000ed54 ++#define CM3_MMFR2 0xe000ed58 ++#define CM3_MMFR3 0xe000ed5c ++#define CM3_ISAR0 0xe000ed60 ++#define CM3_ISAR1 0xe000ed64 ++#define CM3_ISAR2 0xe000ed68 ++#define CM3_ISAR3 0xe000ed6c ++#define CM3_ISAR4 0xe000ed70 ++#define CM3_ISAR5 0xe000ed74 ++ ++#define CM3_MPUTYPE 0xe000ed90 ++#define CM3_MPUCTRL 0xe000ed94 ++#define CM3_REGNUM 0xe000ed98 ++#define CM3_REGBAR 0xe000ed9c ++#define CM3_REGASZ 0xe000eda0 ++#define CM3_AL1BAR 0xe000eda4 ++#define CM3_AL1ASZ 0xe000eda8 ++#define CM3_AL2BAR 0xe000edac ++#define CM3_AL2ASZ 0xe000edb0 ++#define CM3_AL3BAR 0xe000edb4 ++#define CM3_AL3ASZ 0xe000edb8 ++ ++#define CM3_DBG_HCSR 0xe000edf0 /* Debug Halting Control and Status Reg */ ++#define CM3_DBG_CRSR 0xe000edf4 /* Debug Core Register Selector Reg */ ++#define CM3_DBG_CRDR 0xe000edf8 /* Debug Core Register Data Reg */ ++#define CM3_DBG_EMCR 0xe000edfc /* Debug Exception and Monitor Control Reg */ ++#define CM3_DBG_EMCR_TRCENA (1U << 24) ++#define CM3_DBG_EMCR_MON_EN (1U << 16) ++ ++/* Trap types */ ++#define TR_RST 1 /* Reset */ ++#define TR_NMI 2 /* NMI */ ++#define TR_FAULT 3 /* Hard Fault */ ++#define TR_MM 4 /* Memory Management */ ++#define TR_BUS 5 /* Bus Fault */ ++#define TR_USAGE 6 /* Usage Fault */ ++#define TR_SVC 11 /* SVCall */ ++#define TR_DMON 12 /* Debug Monitor */ ++#define TR_PENDSV 14 /* PendSV */ ++#define TR_SYSTICK 15 /* SysTick */ ++#define TR_ISR 16 /* External Interrupts start here */ ++ ++#define TR_BAD 256 /* Bad trap: Not used by CM3 */ ++ ++/* Offsets of automatically saved registers from sp upon trap */ ++#define CM3_TROFF_R0 0 ++#define CM3_TROFF_R1 4 ++#define CM3_TROFF_R2 8 ++#define CM3_TROFF_R3 12 ++#define CM3_TROFF_R12 16 ++#define CM3_TROFF_LR 20 ++#define CM3_TROFF_PC 24 ++#define CM3_TROFF_xPSR 28 ++ ++#elif defined(__ARM_ARCH_7A__) /* Cortex-A9 */ ++/* Fields in cpsr */ ++#define PS_USR 0x00000010 /* Mode: User */ ++#define PS_FIQ 0x00000011 /* Mode: FIQ */ ++#define PS_IRQ 0x00000012 /* Mode: IRQ */ ++#define PS_SVC 0x00000013 /* Mode: Supervisor */ ++#define PS_ABT 0x00000017 /* Mode: Abort */ ++#define PS_UND 0x0000001b /* Mode: Undefined */ ++#define PS_SYS 0x0000001f /* Mode: System */ ++#define PS_MM 0x0000001f /* Mode bits mask */ ++#define PS_T 0x00000020 /* Thumb mode */ ++#define PS_F 0x00000040 /* FIQ disable */ ++#define PS_I 0x00000080 /* IRQ disable */ ++#define PS_A 0x00000100 /* Imprecise abort */ ++#define PS_E 0x00000200 /* Endianess */ ++#define PS_IT72 0x0000fc00 /* IT[7:2] */ ++#define PS_GE 0x000f0000 /* IT[7:2] */ ++#define PS_J 0x01000000 /* Java state */ ++#define PS_IT10 0x06000000 /* IT[1:0] */ ++#define PS_Q 0x08000000 /* Sticky overflow */ ++#define PS_V 0x10000000 /* Overflow cc */ ++#define PS_C 0x20000000 /* Carry cc */ ++#define PS_Z 0x40000000 /* Zero cc */ ++#define PS_N 0x80000000 /* Negative cc */ ++ ++/* Trap types */ ++#define TR_RST 0 /* Reset trap */ ++#define TR_UND 1 /* Indefined instruction trap */ ++#define TR_SWI 2 /* Software intrrupt */ ++#define TR_IAB 3 /* Instruction fetch abort */ ++#define TR_DAB 4 /* Data access abort */ ++#define TR_BAD 5 /* Bad trap: Not used by ARM */ ++#define TR_IRQ 6 /* Interrupt */ ++#define TR_FIQ 7 /* Fast interrupt */ ++ ++/* ++ * Memory segments (32bit kernel mode addresses) ++ */ ++#define PHYSADDR_MASK 0xffffffff ++ ++/* ++ * Map an address to a certain kernel segment ++ */ ++#undef PHYSADDR ++#define PHYSADDR(a) (_ULCAST_(a) & PHYSADDR_MASK) ++#else /* !__ARM_ARCH_7M__ */ ++ ++/* Fields in cpsr */ ++#define PS_USR 0x00000010 /* Mode: User */ ++#define PS_FIQ 0x00000011 /* Mode: FIQ */ ++#define PS_IRQ 0x00000012 /* Mode: IRQ */ ++#define PS_SVC 0x00000013 /* Mode: Supervisor */ ++#define PS_ABT 0x00000017 /* Mode: Abort */ ++#define PS_UND 0x0000001b /* Mode: Undefined */ ++#define PS_SYS 0x0000001f /* Mode: System */ ++#define PS_MM 0x0000001f /* Mode bits mask */ ++#define PS_T 0x00000020 /* Thumb mode */ ++#define PS_F 0x00000040 /* FIQ disable */ ++#define PS_I 0x00000080 /* IRQ disable */ ++#define PS_A 0x00000100 /* Imprecise abort */ ++#define PS_E 0x00000200 /* Endianess */ ++#define PS_IT72 0x0000fc00 /* IT[7:2] */ ++#define PS_GE 0x000f0000 /* IT[7:2] */ ++#define PS_J 0x01000000 /* Java state */ ++#define PS_IT10 0x06000000 /* IT[1:0] */ ++#define PS_Q 0x08000000 /* Sticky overflow */ ++#define PS_V 0x10000000 /* Overflow cc */ ++#define PS_C 0x20000000 /* Carry cc */ ++#define PS_Z 0x40000000 /* Zero cc */ ++#define PS_N 0x80000000 /* Negative cc */ ++ ++/* Trap types */ ++#define TR_RST 0 /* Reset trap */ ++#define TR_UND 1 /* Indefined instruction trap */ ++#define TR_SWI 2 /* Software intrrupt */ ++#define TR_IAB 3 /* Instruction fetch abort */ ++#define TR_DAB 4 /* Data access abort */ ++#define TR_BAD 5 /* Bad trap: Not used by ARM */ ++#define TR_IRQ 6 /* Interrupt */ ++#define TR_FIQ 7 /* Fast interrupt */ ++ ++#ifdef BCMDBG_ARMRST ++#define TR_ARMRST 0xF /* Debug facility to trap Arm reset */ ++#endif ++ ++/* used to fill an overlay region with nop's */ ++#define NOP_UINT32 0x46c046c0 ++ ++ ++#define mrc(cp, a, b, n) \ ++({ \ ++ int __res; \ ++ __asm__ __volatile__("\tmrc\tp"STR(cp)", 0, %0, c"STR(a)", c"STR(b)", "STR(n) \ ++ :"=r" (__res)); \ ++ __res; \ ++}) ++ ++ ++#endif /* !__ARM_ARCH_7M__ */ ++ ++/* Pieces of a CPU Id */ ++#define CID_IMPL 0xff000000 /* Implementor: 0x41 for ARM Ltd. */ ++#define CID_VARIANT 0x00f00000 ++#define CID_ARCH 0x000f0000 ++#define CID_PART 0x0000fff0 ++#define CID_REV 0x0000000f ++#define CID_MASK (CID_IMPL | CID_ARCH | CID_PART) ++ ++#endif /* _ARMINC_H */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcm_cfg.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcm_cfg.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/bcm_cfg.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcm_cfg.h 2017-11-09 17:53:43.915303000 +0800 +@@ -0,0 +1,28 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * BCM common config options ++ * ++ * $Id: bcm_cfg.h 294399 2011-11-07 03:31:22Z $ ++ */ ++ ++#ifndef _bcm_cfg_h_ ++#define _bcm_cfg_h_ ++#if defined(__NetBSD__) || defined(__FreeBSD__) ++#if defined(_KERNEL) ++#include ++#endif /* defined(_KERNEL) */ ++#endif /* defined(__NetBSD__) || defined(__FreeBSD__) */ ++#endif /* _bcm_cfg_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcm_mpool_pub.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcm_mpool_pub.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/bcm_mpool_pub.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcm_mpool_pub.h 2017-11-09 17:53:43.916305000 +0800 +@@ -0,0 +1,355 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Memory pools library, Public interface ++ * ++ * API Overview ++ * ++ * This package provides a memory allocation subsystem based on pools of ++ * homogenous objects. ++ * ++ * Instrumentation is available for reporting memory utilization both ++ * on a per-data-structure basis and system wide. ++ * ++ * There are two main types defined in this API. ++ * ++ * pool manager: A singleton object that acts as a factory for ++ * pool allocators. It also is used for global ++ * instrumentation, such as reporting all blocks ++ * in use across all data structures. The pool manager ++ * creates and provides individual memory pools ++ * upon request to application code. ++ * ++ * memory pool: An object for allocating homogenous memory blocks. ++ * ++ * Global identifiers in this module use the following prefixes: ++ * bcm_mpm_* Memory pool manager ++ * bcm_mp_* Memory pool ++ * ++ * There are two main types of memory pools: ++ * ++ * prealloc: The contiguous memory block of objects can either be supplied ++ * by the client or malloc'ed by the memory manager. The objects are ++ * allocated out of a block of memory and freed back to the block. ++ * ++ * heap: The memory pool allocator uses the heap (malloc/free) for memory. ++ * In this case, the pool allocator is just providing statistics ++ * and instrumentation on top of the heap, without modifying the heap ++ * allocation implementation. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _BCM_MPOOL_PUB_H ++#define _BCM_MPOOL_PUB_H 1 ++ ++#include /* needed for uint16 */ ++ ++ ++/* ++************************************************************************** ++* ++* Type definitions, handles ++* ++************************************************************************** ++*/ ++ ++/* Forward declaration of OSL handle. */ ++struct osl_info; ++ ++/* Forward declaration of string buffer. */ ++struct bcmstrbuf; ++ ++/* ++ * Opaque type definition for the pool manager handle. This object is used for global ++ * memory pool operations such as obtaining a new pool, deleting a pool, iterating and ++ * instrumentation/debugging. ++ */ ++struct bcm_mpm_mgr; ++typedef struct bcm_mpm_mgr *bcm_mpm_mgr_h; ++ ++/* ++ * Opaque type definition for an instance of a pool. This handle is used for allocating ++ * and freeing memory through the pool, as well as management/instrumentation on this ++ * specific pool. ++ */ ++struct bcm_mp_pool; ++typedef struct bcm_mp_pool *bcm_mp_pool_h; ++ ++ ++/* ++ * To make instrumentation more readable, every memory ++ * pool must have a readable name. Pool names are up to ++ * 8 bytes including '\0' termination. (7 printable characters.) ++ */ ++#define BCM_MP_NAMELEN 8 ++ ++ ++/* ++ * Type definition for pool statistics. ++ */ ++typedef struct bcm_mp_stats { ++ char name[BCM_MP_NAMELEN]; /* Name of this pool. */ ++ unsigned int objsz; /* Object size allocated in this pool */ ++ uint16 nobj; /* Total number of objects in this pool */ ++ uint16 num_alloc; /* Number of objects currently allocated */ ++ uint16 high_water; /* Max number of allocated objects. */ ++ uint16 failed_alloc; /* Failed allocations. */ ++} bcm_mp_stats_t; ++ ++ ++/* ++************************************************************************** ++* ++* API Routines on the pool manager. ++* ++************************************************************************** ++*/ ++ ++/* ++ * bcm_mpm_init() - initialize the whole memory pool system. ++ * ++ * Parameters: ++ * osh: INPUT Operating system handle. Needed for heap memory allocation. ++ * max_pools: INPUT Maximum number of mempools supported. ++ * mgr: OUTPUT The handle is written with the new pools manager object/handle. ++ * ++ * Returns: ++ * BCME_OK Object initialized successfully. May be used. ++ * BCME_NOMEM Initialization failed due to no memory. Object must not be used. ++ */ ++int bcm_mpm_init(struct osl_info *osh, int max_pools, bcm_mpm_mgr_h *mgrp); ++ ++ ++/* ++ * bcm_mpm_deinit() - de-initialize the whole memory pool system. ++ * ++ * Parameters: ++ * mgr: INPUT Pointer to pool manager handle. ++ * ++ * Returns: ++ * BCME_OK Memory pool manager successfully de-initialized. ++ * other Indicated error occured during de-initialization. ++ */ ++int bcm_mpm_deinit(bcm_mpm_mgr_h *mgrp); ++ ++/* ++ * bcm_mpm_create_prealloc_pool() - Create a new pool for fixed size objects. The ++ * pool uses a contiguous block of pre-alloced ++ * memory. The memory block may either be provided ++ * by the client or dynamically allocated by the ++ * pool manager. ++ * ++ * Parameters: ++ * mgr: INPUT The handle to the pool manager ++ * obj_sz: INPUT Size of objects that will be allocated by the new pool ++ * Must be >= sizeof(void *). ++ * nobj: INPUT Maximum number of concurrently existing objects to support ++ * memstart INPUT Pointer to the memory to use, or NULL to malloc() ++ * memsize INPUT Number of bytes referenced from memstart (for error checking). ++ * Must be 0 if 'memstart' is NULL. ++ * poolname INPUT For instrumentation, the name of the pool ++ * newp: OUTPUT The handle for the new pool, if creation is successful ++ * ++ * Returns: ++ * BCME_OK Pool created ok. ++ * other Pool not created due to indicated error. newpoolp set to NULL. ++ * ++ * ++ */ ++int bcm_mpm_create_prealloc_pool(bcm_mpm_mgr_h mgr, ++ unsigned int obj_sz, ++ int nobj, ++ void *memstart, ++ unsigned int memsize, ++ char poolname[BCM_MP_NAMELEN], ++ bcm_mp_pool_h *newp); ++ ++ ++/* ++ * bcm_mpm_delete_prealloc_pool() - Delete a memory pool. This should only be called after ++ * all memory objects have been freed back to the pool. ++ * ++ * Parameters: ++ * mgr: INPUT The handle to the pools manager ++ * pool: INPUT The handle of the pool to delete ++ * ++ * Returns: ++ * BCME_OK Pool deleted ok. ++ * other Pool not deleted due to indicated error. ++ * ++ */ ++int bcm_mpm_delete_prealloc_pool(bcm_mpm_mgr_h mgr, bcm_mp_pool_h *poolp); ++ ++/* ++ * bcm_mpm_create_heap_pool() - Create a new pool for fixed size objects. The memory ++ * pool allocator uses the heap (malloc/free) for memory. ++ * In this case, the pool allocator is just providing ++ * statistics and instrumentation on top of the heap, ++ * without modifying the heap allocation implementation. ++ * ++ * Parameters: ++ * mgr: INPUT The handle to the pool manager ++ * obj_sz: INPUT Size of objects that will be allocated by the new pool ++ * poolname INPUT For instrumentation, the name of the pool ++ * newp: OUTPUT The handle for the new pool, if creation is successful ++ * ++ * Returns: ++ * BCME_OK Pool created ok. ++ * other Pool not created due to indicated error. newpoolp set to NULL. ++ * ++ * ++ */ ++int bcm_mpm_create_heap_pool(bcm_mpm_mgr_h mgr, unsigned int obj_sz, ++ char poolname[BCM_MP_NAMELEN], ++ bcm_mp_pool_h *newp); ++ ++ ++/* ++ * bcm_mpm_delete_heap_pool() - Delete a memory pool. This should only be called after ++ * all memory objects have been freed back to the pool. ++ * ++ * Parameters: ++ * mgr: INPUT The handle to the pools manager ++ * pool: INPUT The handle of the pool to delete ++ * ++ * Returns: ++ * BCME_OK Pool deleted ok. ++ * other Pool not deleted due to indicated error. ++ * ++ */ ++int bcm_mpm_delete_heap_pool(bcm_mpm_mgr_h mgr, bcm_mp_pool_h *poolp); ++ ++ ++/* ++ * bcm_mpm_stats() - Return stats for all pools ++ * ++ * Parameters: ++ * mgr: INPUT The handle to the pools manager ++ * stats: OUTPUT Array of pool statistics. ++ * nentries: MOD Max elements in 'stats' array on INPUT. Actual number ++ * of array elements copied to 'stats' on OUTPUT. ++ * ++ * Returns: ++ * BCME_OK Ok ++ * other Error getting stats. ++ * ++ */ ++int bcm_mpm_stats(bcm_mpm_mgr_h mgr, bcm_mp_stats_t *stats, int *nentries); ++ ++ ++/* ++ * bcm_mpm_dump() - Display statistics on all pools ++ * ++ * Parameters: ++ * mgr: INPUT The handle to the pools manager ++ * b: OUTPUT Output buffer. ++ * ++ * Returns: ++ * BCME_OK Ok ++ * other Error during dump. ++ * ++ */ ++int bcm_mpm_dump(bcm_mpm_mgr_h mgr, struct bcmstrbuf *b); ++ ++ ++/* ++ * bcm_mpm_get_obj_size() - The size of memory objects may need to be padded to ++ * compensate for alignment requirements of the objects. ++ * This function provides the padded object size. If clients ++ * pre-allocate a memory slab for a memory pool, the ++ * padded object size should be used by the client to allocate ++ * the memory slab (in order to provide sufficent space for ++ * the maximum number of objects). ++ * ++ * Parameters: ++ * mgr: INPUT The handle to the pools manager. ++ * obj_sz: INPUT Input object size. ++ * padded_obj_sz: OUTPUT Padded object size. ++ * ++ * Returns: ++ * BCME_OK Ok ++ * BCME_BADARG Bad arguments. ++ * ++ */ ++int bcm_mpm_get_obj_size(bcm_mpm_mgr_h mgr, unsigned int obj_sz, unsigned int *padded_obj_sz); ++ ++ ++/* ++*************************************************************************** ++* ++* API Routines on a specific pool. ++* ++*************************************************************************** ++*/ ++ ++ ++/* ++ * bcm_mp_alloc() - Allocate a memory pool object. ++ * ++ * Parameters: ++ * pool: INPUT The handle to the pool. ++ * ++ * Returns: ++ * A pointer to the new object. NULL on error. ++ * ++ */ ++void* bcm_mp_alloc(bcm_mp_pool_h pool); ++ ++/* ++ * bcm_mp_free() - Free a memory pool object. ++ * ++ * Parameters: ++ * pool: INPUT The handle to the pool. ++ * objp: INPUT A pointer to the object to free. ++ * ++ * Returns: ++ * BCME_OK Ok ++ * other Error during free. ++ * ++ */ ++int bcm_mp_free(bcm_mp_pool_h pool, void *objp); ++ ++/* ++ * bcm_mp_stats() - Return stats for this pool ++ * ++ * Parameters: ++ * pool: INPUT The handle to the pool ++ * stats: OUTPUT Pool statistics ++ * ++ * Returns: ++ * BCME_OK Ok ++ * other Error getting statistics. ++ * ++ */ ++int bcm_mp_stats(bcm_mp_pool_h pool, bcm_mp_stats_t *stats); ++ ++ ++/* ++ * bcm_mp_dump() - Dump a pool ++ * ++ * Parameters: ++ * pool: INPUT The handle to the pool ++ * b OUTPUT Output buffer ++ * ++ * Returns: ++ * BCME_OK Ok ++ * other Error during dump. ++ * ++ */ ++int bcm_mp_dump(bcm_mp_pool_h pool, struct bcmstrbuf *b); ++ ++ ++#endif /* _BCM_MPOOL_PUB_H */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmcdc.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmcdc.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmcdc.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmcdc.h 2017-11-09 17:53:43.917296000 +0800 +@@ -0,0 +1,122 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * CDC network driver ioctl/indication encoding ++ * Broadcom 802.11abg Networking Device Driver ++ * ++ * Definitions subject to change without notice. ++ * ++ * $Id: bcmcdc.h 291086 2011-10-21 01:17:24Z $ ++ */ ++#ifndef _bcmcdc_h_ ++#define _bcmcdc_h_ ++#include ++ ++typedef struct cdc_ioctl { ++ uint32 cmd; /* ioctl command value */ ++ uint32 len; /* lower 16: output buflen; upper 16: input buflen (excludes header) */ ++ uint32 flags; /* flag defns given below */ ++ uint32 status; /* status code returned from the device */ ++} cdc_ioctl_t; ++ ++/* Max valid buffer size that can be sent to the dongle */ ++#define CDC_MAX_MSG_SIZE ETHER_MAX_LEN ++ ++/* len field is divided into input and output buffer lengths */ ++#define CDCL_IOC_OUTLEN_MASK 0x0000FFFF /* maximum or expected response length, */ ++ /* excluding IOCTL header */ ++#define CDCL_IOC_OUTLEN_SHIFT 0 ++#define CDCL_IOC_INLEN_MASK 0xFFFF0000 /* input buffer length, excluding IOCTL header */ ++#define CDCL_IOC_INLEN_SHIFT 16 ++ ++/* CDC flag definitions */ ++#define CDCF_IOC_ERROR 0x01 /* 0=success, 1=ioctl cmd failed */ ++#define CDCF_IOC_SET 0x02 /* 0=get, 1=set cmd */ ++#define CDCF_IOC_OVL_IDX_MASK 0x3c /* overlay region index mask */ ++#define CDCF_IOC_OVL_RSV 0x40 /* 1=reserve this overlay region */ ++#define CDCF_IOC_OVL 0x80 /* 1=this ioctl corresponds to an overlay */ ++#define CDCF_IOC_ACTION_MASK 0xfe /* SET/GET, OVL_IDX, OVL_RSV, OVL mask */ ++#define CDCF_IOC_ACTION_SHIFT 1 /* SET/GET, OVL_IDX, OVL_RSV, OVL shift */ ++#define CDCF_IOC_IF_MASK 0xF000 /* I/F index */ ++#define CDCF_IOC_IF_SHIFT 12 ++#define CDCF_IOC_ID_MASK 0xFFFF0000 /* used to uniquely id an ioctl req/resp pairing */ ++#define CDCF_IOC_ID_SHIFT 16 /* # of bits of shift for ID Mask */ ++ ++#define CDC_IOC_IF_IDX(flags) (((flags) & CDCF_IOC_IF_MASK) >> CDCF_IOC_IF_SHIFT) ++#define CDC_IOC_ID(flags) (((flags) & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT) ++ ++#define CDC_GET_IF_IDX(hdr) \ ++ ((int)((((hdr)->flags) & CDCF_IOC_IF_MASK) >> CDCF_IOC_IF_SHIFT)) ++#define CDC_SET_IF_IDX(hdr, idx) \ ++ ((hdr)->flags = (((hdr)->flags & ~CDCF_IOC_IF_MASK) | ((idx) << CDCF_IOC_IF_SHIFT))) ++ ++/* ++ * BDC header ++ * ++ * The BDC header is used on data packets to convey priority across USB. ++ */ ++ ++#define BDC_HEADER_LEN 4 ++ ++#define BDC_PROTO_VER_1 1 /* Old Protocol version */ ++#define BDC_PROTO_VER 2 /* Protocol version */ ++ ++#define BDC_FLAG_VER_MASK 0xf0 /* Protocol version mask */ ++#define BDC_FLAG_VER_SHIFT 4 /* Protocol version shift */ ++ ++#define BDC_FLAG__UNUSED 0x03 /* Unassigned */ ++#define BDC_FLAG_SUM_GOOD 0x04 /* Dongle has verified good RX checksums */ ++#define BDC_FLAG_SUM_NEEDED 0x08 /* Dongle needs to do TX checksums */ ++ ++#define BDC_PRIORITY_MASK 0x7 ++ ++#define BDC_FLAG2_FC_FLAG 0x10 /* flag to indicate if pkt contains */ ++ /* FLOW CONTROL info only */ ++#define BDC_PRIORITY_FC_SHIFT 4 /* flow control info shift */ ++ ++#define BDC_FLAG2_IF_MASK 0x0f /* APSTA: interface on which the packet was received */ ++#define BDC_FLAG2_IF_SHIFT 0 ++#define BDC_FLAG2_PAD_MASK 0xf0 ++#define BDC_FLAG_PAD_MASK 0x03 ++#define BDC_FLAG2_PAD_SHIFT 2 ++#define BDC_FLAG_PAD_SHIFT 0 ++#define BDC_FLAG2_PAD_IDX 0x3c ++#define BDC_FLAG_PAD_IDX 0x03 ++#define BDC_GET_PAD_LEN(hdr) \ ++ ((int)(((((hdr)->flags2) & BDC_FLAG2_PAD_MASK) >> BDC_FLAG2_PAD_SHIFT) | \ ++ ((((hdr)->flags) & BDC_FLAG_PAD_MASK) >> BDC_FLAG_PAD_SHIFT))) ++#define BDC_SET_PAD_LEN(hdr, idx) \ ++ ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_PAD_MASK) | \ ++ (((idx) & BDC_FLAG2_PAD_IDX) << BDC_FLAG2_PAD_SHIFT))); \ ++ ((hdr)->flags = (((hdr)->flags & ~BDC_FLAG_PAD_MASK) | \ ++ (((idx) & BDC_FLAG_PAD_IDX) << BDC_FLAG_PAD_SHIFT))) ++ ++#define BDC_GET_IF_IDX(hdr) \ ++ ((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT)) ++#define BDC_SET_IF_IDX(hdr, idx) \ ++ ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | ((idx) << BDC_FLAG2_IF_SHIFT))) ++ ++struct bdc_header { ++ uint8 flags; /* Flags */ ++ uint8 priority; /* 802.1d Priority 0:2 bits, 4:7 USB flow control info */ ++ uint8 flags2; ++ uint8 dataOffset; /* Offset from end of BDC header to packet data, in ++ * 4-byte words. Leaves room for optional headers. ++ */ ++}; ++ ++#define BDC_PROTO_VER_1 1 /* Old Protocol version */ ++ ++#endif /* _bcmcdc_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmdefs.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmdefs.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmdefs.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmdefs.h 2017-11-09 17:53:43.918300000 +0800 +@@ -0,0 +1,332 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Misc system wide definitions ++ * ++ * $Id: bcmdefs.h 316696 2012-02-23 03:29:35Z $ ++ */ ++ ++#ifndef _bcmdefs_h_ ++#define _bcmdefs_h_ ++ ++/* ++ * One doesn't need to include this file explicitly, gets included automatically if ++ * typedefs.h is included. ++ */ ++ ++/* Use BCM_REFERENCE to suppress warnings about intentionally-unused function ++ * arguments or local variables. ++ */ ++#define BCM_REFERENCE(data) ((void)(data)) ++ ++/* Compile-time assert can be used in place of ASSERT if the expression evaluates ++ * to a constant at compile time. ++ */ ++#define STATIC_ASSERT(expr) { \ ++ /* Make sure the expression is constant. */ \ ++ typedef enum { _STATIC_ASSERT_NOT_CONSTANT = (expr) } _static_assert_e; \ ++ /* Make sure the expression is true. */ \ ++ typedef char STATIC_ASSERT_FAIL[(expr) ? 1 : -1]; \ ++} ++ ++/* Reclaiming text and data : ++ * The following macros specify special linker sections that can be reclaimed ++ * after a system is considered 'up'. ++ * BCMATTACHFN is also used for detach functions (it's not worth having a BCMDETACHFN, ++ * as in most cases, the attach function calls the detach function to clean up on error). ++ */ ++#ifdef DONGLEBUILD ++ ++extern bool bcmreclaimed; ++extern bool attach_part_reclaimed; ++ ++#define BCMATTACHDATA(_data) __attribute__ ((__section__ (".dataini2." #_data))) _data ++#define BCMATTACHFN(_fn) __attribute__ ((__section__ (".textini2." #_fn), noinline)) _fn ++ ++#ifndef PREATTACH_NORECLAIM ++#define BCMPREATTACHDATA(_data) __attribute__ ((__section__ (".dataini3." #_data))) _data ++#define BCMPREATTACHFN(_fn) __attribute__ ((__section__ (".textini3." #_fn), noinline)) _fn ++#else ++#define BCMPREATTACHDATA(_data) __attribute__ ((__section__ (".dataini2." #_data))) _data ++#define BCMPREATTACHFN(_fn) __attribute__ ((__section__ (".textini2." #_fn), noinline)) _fn ++#endif ++ ++#if defined(BCMRECLAIM) ++#define BCMINITDATA(_data) __attribute__ ((__section__ (".dataini1." #_data))) _data ++#define BCMINITFN(_fn) __attribute__ ((__section__ (".textini1." #_fn), noinline)) _fn ++#define CONST ++#else ++#define BCMINITDATA(_data) _data ++#define BCMINITFN(_fn) _fn ++#define CONST const ++#endif ++ ++/* Non-manufacture or internal attach function/dat */ ++#if !defined(WLTEST) ++#define BCMNMIATTACHFN(_fn) BCMATTACHFN(_fn) ++#define BCMNMIATTACHDATA(_data) BCMATTACHDATA(_data) ++#else ++#define BCMNMIATTACHFN(_fn) _fn ++#define BCMNMIATTACHDATA(_data) _data ++#endif ++ ++#define BCMUNINITFN(_fn) _fn ++ ++#define BCMFASTPATH ++#else /* DONGLEBUILD */ ++ ++#define bcmreclaimed 0 ++#define BCMATTACHDATA(_data) _data ++#define BCMATTACHFN(_fn) _fn ++#define BCMPREATTACHDATA(_data) _data ++#define BCMPREATTACHFN(_fn) _fn ++#define BCMINITDATA(_data) _data ++#define BCMINITFN(_fn) _fn ++#define BCMUNINITFN(_fn) _fn ++#define BCMNMIATTACHFN(_fn) _fn ++#define BCMNMIATTACHDATA(_data) _data ++#define CONST const ++#if defined(__ARM_ARCH_7A__) ++#define BCM47XX_CA9 ++#else ++#undef BCM47XX_CA9 ++#endif ++#ifndef BCMFASTPATH ++#if defined(mips) || defined(BCM47XX_CA9) ++#define BCMFASTPATH __attribute__ ((__section__ (".text.fastpath"))) ++#define BCMFASTPATH_HOST __attribute__ ((__section__ (".text.fastpath_host"))) ++#else ++#define BCMFASTPATH ++#define BCMFASTPATH_HOST ++#endif ++#endif /* BCMFASTPATH */ ++ ++#endif /* DONGLEBUILD */ ++ ++#if defined(BCMROMBUILD) ++typedef struct { ++ uint16 esiz; ++ uint16 cnt; ++ void *addr; ++} bcmromdat_patch_t; ++#endif ++ ++/* Put some library data/code into ROM to reduce RAM requirements */ ++#if defined(BCMROMBUILD) && !defined(BCMROMSYMGEN_BUILD) && !defined(BCMJMPTBL_TCAM) ++#include ++#define STATIC static ++#else /* !BCMROMBUILD */ ++#define BCMROMDATA(_data) _data ++#define BCMROMDAT_NAME(_data) _data ++#define BCMROMFN(_fn) _fn ++#define BCMROMFN_NAME(_fn) _fn ++#define STATIC static ++#define BCMROMDAT_ARYSIZ(data) ARRAYSIZE(data) ++#define BCMROMDAT_SIZEOF(data) sizeof(data) ++#define BCMROMDAT_APATCH(data) ++#define BCMROMDAT_SPATCH(data) ++#endif /* !BCMROMBUILD */ ++ ++/* Bus types */ ++#define SI_BUS 0 /* SOC Interconnect */ ++#define PCI_BUS 1 /* PCI target */ ++#define PCMCIA_BUS 2 /* PCMCIA target */ ++#define SDIO_BUS 3 /* SDIO target */ ++#define JTAG_BUS 4 /* JTAG */ ++#define USB_BUS 5 /* USB (does not support R/W REG) */ ++#define SPI_BUS 6 /* gSPI target */ ++#define RPC_BUS 7 /* RPC target */ ++ ++/* Allows size optimization for single-bus image */ ++#ifdef BCMBUSTYPE ++#define BUSTYPE(bus) (BCMBUSTYPE) ++#else ++#define BUSTYPE(bus) (bus) ++#endif ++ ++/* Allows size optimization for single-backplane image */ ++#ifdef BCMCHIPTYPE ++#define CHIPTYPE(bus) (BCMCHIPTYPE) ++#else ++#define CHIPTYPE(bus) (bus) ++#endif ++ ++ ++/* Allows size optimization for SPROM support */ ++#if defined(BCMSPROMBUS) ++#define SPROMBUS (BCMSPROMBUS) ++#elif defined(SI_PCMCIA_SROM) ++#define SPROMBUS (PCMCIA_BUS) ++#else ++#define SPROMBUS (PCI_BUS) ++#endif ++ ++/* Allows size optimization for single-chip image */ ++#ifdef BCMCHIPID ++#define CHIPID(chip) (BCMCHIPID) ++#else ++#define CHIPID(chip) (chip) ++#endif ++ ++#ifdef BCMCHIPREV ++#define CHIPREV(rev) (BCMCHIPREV) ++#else ++#define CHIPREV(rev) (rev) ++#endif ++ ++/* Defines for DMA Address Width - Shared between OSL and HNDDMA */ ++#define DMADDR_MASK_32 0x0 /* Address mask for 32-bits */ ++#define DMADDR_MASK_30 0xc0000000 /* Address mask for 30-bits */ ++#define DMADDR_MASK_0 0xffffffff /* Address mask for 0-bits (hi-part) */ ++ ++#define DMADDRWIDTH_30 30 /* 30-bit addressing capability */ ++#define DMADDRWIDTH_32 32 /* 32-bit addressing capability */ ++#define DMADDRWIDTH_63 63 /* 64-bit addressing capability */ ++#define DMADDRWIDTH_64 64 /* 64-bit addressing capability */ ++ ++#ifdef BCMDMA64OSL ++typedef struct { ++ uint32 loaddr; ++ uint32 hiaddr; ++} dma64addr_t; ++ ++typedef dma64addr_t dmaaddr_t; ++#define PHYSADDRHI(_pa) ((_pa).hiaddr) ++#define PHYSADDRHISET(_pa, _val) \ ++ do { \ ++ (_pa).hiaddr = (_val); \ ++ } while (0) ++#define PHYSADDRLO(_pa) ((_pa).loaddr) ++#define PHYSADDRLOSET(_pa, _val) \ ++ do { \ ++ (_pa).loaddr = (_val); \ ++ } while (0) ++ ++#else ++typedef unsigned long dmaaddr_t; ++#define PHYSADDRHI(_pa) (0) ++#define PHYSADDRHISET(_pa, _val) ++#define PHYSADDRLO(_pa) ((_pa)) ++#define PHYSADDRLOSET(_pa, _val) \ ++ do { \ ++ (_pa) = (_val); \ ++ } while (0) ++#endif /* BCMDMA64OSL */ ++ ++/* One physical DMA segment */ ++typedef struct { ++ dmaaddr_t addr; ++ uint32 length; ++} hnddma_seg_t; ++ ++#if defined(MACOSX) ++/* In MacOS, the OS API may return large number of segments. Setting this number lower ++ * will result in failure of dma map ++ */ ++#define MAX_DMA_SEGS 8 ++#elif defined(__NetBSD__) ++/* In NetBSD we also want more segments because the lower level mbuf mapping api might ++ * allocate a large number of segments ++ */ ++#define MAX_DMA_SEGS 16 ++#else ++#define MAX_DMA_SEGS 4 ++#endif ++ ++ ++typedef struct { ++ void *oshdmah; /* Opaque handle for OSL to store its information */ ++ uint origsize; /* Size of the virtual packet */ ++ uint nsegs; ++ hnddma_seg_t segs[MAX_DMA_SEGS]; ++} hnddma_seg_map_t; ++ ++ ++/* packet headroom necessary to accommodate the largest header in the system, (i.e TXOFF). ++ * By doing, we avoid the need to allocate an extra buffer for the header when bridging to WL. ++ * There is a compile time check in wlc.c which ensure that this value is at least as big ++ * as TXOFF. This value is used in dma_rxfill (hnddma.c). ++ */ ++ ++#if defined(BCM_RPC_NOCOPY) || defined(BCM_RCP_TXNOCOPY) ++/* add 40 bytes to allow for extra RPC header and info */ ++#define BCMEXTRAHDROOM 260 ++#else /* BCM_RPC_NOCOPY || BCM_RPC_TXNOCOPY */ ++#define BCMEXTRAHDROOM 204 ++#endif /* BCM_RPC_NOCOPY || BCM_RPC_TXNOCOPY */ ++ ++/* Packet alignment for most efficient SDIO (can change based on platform) */ ++#ifndef SDALIGN ++#define SDALIGN 32 ++#endif ++ ++/* Headroom required for dongle-to-host communication. Packets allocated ++ * locally in the dongle (e.g. for CDC ioctls or RNDIS messages) should ++ * leave this much room in front for low-level message headers which may ++ * be needed to get across the dongle bus to the host. (These messages ++ * don't go over the network, so room for the full WL header above would ++ * be a waste.). ++*/ ++#define BCMDONGLEHDRSZ 12 ++#define BCMDONGLEPADSZ 16 ++ ++#define BCMDONGLEOVERHEAD (BCMDONGLEHDRSZ + BCMDONGLEPADSZ) ++ ++#ifdef BCMDBG ++ ++#ifndef BCMDBG_ERR ++#define BCMDBG_ERR ++#endif /* BCMDBG_ERR */ ++ ++#define BCMDBG_ASSERT ++ ++#endif /* BCMDBG */ ++ ++ ++/* Macros for doing definition and get/set of bitfields ++ * Usage example, e.g. a three-bit field (bits 4-6): ++ * #define _M BITFIELD_MASK(3) ++ * #define _S 4 ++ * ... ++ * regval = R_REG(osh, ®s->regfoo); ++ * field = GFIELD(regval, ); ++ * regval = SFIELD(regval, , 1); ++ * W_REG(osh, ®s->regfoo, regval); ++ */ ++#define BITFIELD_MASK(width) \ ++ (((unsigned)1 << (width)) - 1) ++#define GFIELD(val, field) \ ++ (((val) >> field ## _S) & field ## _M) ++#define SFIELD(val, field, bits) \ ++ (((val) & (~(field ## _M << field ## _S))) | \ ++ ((unsigned)(bits) << field ## _S)) ++ ++/* define BCMSMALL to remove misc features for memory-constrained environments */ ++#ifdef BCMSMALL ++#undef BCMSPACE ++#define bcmspace FALSE /* if (bcmspace) code is discarded */ ++#else ++#define BCMSPACE ++#define bcmspace TRUE /* if (bcmspace) code is retained */ ++#endif ++ ++/* Max. nvram variable table size */ ++#define MAXSZ_NVRAM_VARS 4096 ++ ++#ifdef EFI ++#define __attribute__(x) /* CSTYLED */ ++#endif ++ ++#endif /* _bcmdefs_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmdevs.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmdevs.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmdevs.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmdevs.h 2017-11-09 17:53:43.920291000 +0800 +@@ -0,0 +1,870 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Broadcom device-specific manifest constants. ++ * ++ * $Id: bcmdevs.h 328955 2012-04-23 09:06:12Z $ ++ */ ++ ++#ifndef _BCMDEVS_H ++#define _BCMDEVS_H ++ ++/* PCI vendor IDs */ ++#define VENDOR_EPIGRAM 0xfeda ++#define VENDOR_BROADCOM 0x14e4 ++#define VENDOR_3COM 0x10b7 ++#define VENDOR_NETGEAR 0x1385 ++#define VENDOR_DIAMOND 0x1092 ++#define VENDOR_INTEL 0x8086 ++#define VENDOR_DELL 0x1028 ++#define VENDOR_HP 0x103c ++#define VENDOR_HP_COMPAQ 0x0e11 ++#define VENDOR_APPLE 0x106b ++#define VENDOR_SI_IMAGE 0x1095 /* Silicon Image, used by Arasan SDIO Host */ ++#define VENDOR_BUFFALO 0x1154 /* Buffalo vendor id */ ++#define VENDOR_TI 0x104c /* Texas Instruments */ ++#define VENDOR_RICOH 0x1180 /* Ricoh */ ++#define VENDOR_JMICRON 0x197b ++ ++ ++/* PCMCIA vendor IDs */ ++#define VENDOR_BROADCOM_PCMCIA 0x02d0 ++ ++/* SDIO vendor IDs */ ++#define VENDOR_BROADCOM_SDIO 0x00BF ++ ++/* DONGLE VID/PIDs */ ++#define BCM_DNGL_VID 0x0a5c ++#define BCM_DNGL_BL_PID_4328 0xbd12 ++#define BCM_DNGL_BL_PID_4322 0xbd13 ++#define BCM_DNGL_BL_PID_4319 0xbd16 ++#define BCM_DNGL_BL_PID_43236 0xbd17 ++#define BCM_DNGL_BL_PID_4332 0xbd18 ++#define BCM_DNGL_BL_PID_4330 0xbd19 ++#define BCM_DNGL_BL_PID_4334 0xbd1a ++#define BCM_DNGL_BL_PID_43239 0xbd1b ++#define BCM_DNGL_BL_PID_4324 0xbd1c ++#define BCM_DNGL_BL_PID_4360 0xbd1d ++#define BCM_DNGL_BL_PID_4335 0xbd20 ++ ++#define BCM_DNGL_BDC_PID 0x0bdc ++#define BCM_DNGL_JTAG_PID 0x4a44 ++ ++/* HW USB BLOCK [CPULESS USB] PIDs */ ++#define BCM_HWUSB_PID_43239 43239 ++ ++/* PCI Device IDs */ ++#define BCM4210_DEVICE_ID 0x1072 /* never used */ ++#define BCM4230_DEVICE_ID 0x1086 /* never used */ ++#define BCM4401_ENET_ID 0x170c /* 4401b0 production enet cards */ ++#define BCM3352_DEVICE_ID 0x3352 /* bcm3352 device id */ ++#define BCM3360_DEVICE_ID 0x3360 /* bcm3360 device id */ ++#define BCM4211_DEVICE_ID 0x4211 ++#define BCM4231_DEVICE_ID 0x4231 ++#define BCM4303_D11B_ID 0x4303 /* 4303 802.11b */ ++#define BCM4311_D11G_ID 0x4311 /* 4311 802.11b/g id */ ++#define BCM4311_D11DUAL_ID 0x4312 /* 4311 802.11a/b/g id */ ++#define BCM4311_D11A_ID 0x4313 /* 4311 802.11a id */ ++#define BCM4328_D11DUAL_ID 0x4314 /* 4328/4312 802.11a/g id */ ++#define BCM4328_D11G_ID 0x4315 /* 4328/4312 802.11g id */ ++#define BCM4328_D11A_ID 0x4316 /* 4328/4312 802.11a id */ ++#define BCM4318_D11G_ID 0x4318 /* 4318 802.11b/g id */ ++#define BCM4318_D11DUAL_ID 0x4319 /* 4318 802.11a/b/g id */ ++#define BCM4318_D11A_ID 0x431a /* 4318 802.11a id */ ++#define BCM4325_D11DUAL_ID 0x431b /* 4325 802.11a/g id */ ++#define BCM4325_D11G_ID 0x431c /* 4325 802.11g id */ ++#define BCM4325_D11A_ID 0x431d /* 4325 802.11a id */ ++#define BCM4306_D11G_ID 0x4320 /* 4306 802.11g */ ++#define BCM4306_D11A_ID 0x4321 /* 4306 802.11a */ ++#define BCM4306_UART_ID 0x4322 /* 4306 uart */ ++#define BCM4306_V90_ID 0x4323 /* 4306 v90 codec */ ++#define BCM4306_D11DUAL_ID 0x4324 /* 4306 dual A+B */ ++#define BCM4306_D11G_ID2 0x4325 /* BCM4306_D11G_ID; INF w/loose binding war */ ++#define BCM4321_D11N_ID 0x4328 /* 4321 802.11n dualband id */ ++#define BCM4321_D11N2G_ID 0x4329 /* 4321 802.11n 2.4Ghz band id */ ++#define BCM4321_D11N5G_ID 0x432a /* 4321 802.11n 5Ghz band id */ ++#define BCM4322_D11N_ID 0x432b /* 4322 802.11n dualband device */ ++#define BCM4322_D11N2G_ID 0x432c /* 4322 802.11n 2.4GHz device */ ++#define BCM4322_D11N5G_ID 0x432d /* 4322 802.11n 5GHz device */ ++#define BCM4329_D11N_ID 0x432e /* 4329 802.11n dualband device */ ++#define BCM4329_D11N2G_ID 0x432f /* 4329 802.11n 2.4G device */ ++#define BCM4329_D11N5G_ID 0x4330 /* 4329 802.11n 5G device */ ++#define BCM4315_D11DUAL_ID 0x4334 /* 4315 802.11a/g id */ ++#define BCM4315_D11G_ID 0x4335 /* 4315 802.11g id */ ++#define BCM4315_D11A_ID 0x4336 /* 4315 802.11a id */ ++#define BCM4319_D11N_ID 0x4337 /* 4319 802.11n dualband device */ ++#define BCM4319_D11N2G_ID 0x4338 /* 4319 802.11n 2.4G device */ ++#define BCM4319_D11N5G_ID 0x4339 /* 4319 802.11n 5G device */ ++#define BCM43231_D11N2G_ID 0x4340 /* 43231 802.11n 2.4GHz device */ ++#define BCM43221_D11N2G_ID 0x4341 /* 43221 802.11n 2.4GHz device */ ++#define BCM43222_D11N_ID 0x4350 /* 43222 802.11n dualband device */ ++#define BCM43222_D11N2G_ID 0x4351 /* 43222 802.11n 2.4GHz device */ ++#define BCM43222_D11N5G_ID 0x4352 /* 43222 802.11n 5GHz device */ ++#define BCM43224_D11N_ID 0x4353 /* 43224 802.11n dualband device */ ++#define BCM43224_D11N_ID_VEN1 0x0576 /* Vendor specific 43224 802.11n db device */ ++#define BCM43226_D11N_ID 0x4354 /* 43226 802.11n dualband device */ ++#define BCM43236_D11N_ID 0x4346 /* 43236 802.11n dualband device */ ++#define BCM43236_D11N2G_ID 0x4347 /* 43236 802.11n 2.4GHz device */ ++#define BCM43236_D11N5G_ID 0x4348 /* 43236 802.11n 5GHz device */ ++#define BCM43225_D11N2G_ID 0x4357 /* 43225 802.11n 2.4GHz device */ ++#define BCM43421_D11N_ID 0xA99D /* 43421 802.11n dualband device */ ++#define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */ ++#define BCM4330_D11N_ID 0x4360 /* 4330 802.11n dualband device */ ++#define BCM4330_D11N2G_ID 0x4361 /* 4330 802.11n 2.4G device */ ++#define BCM4330_D11N5G_ID 0x4362 /* 4330 802.11n 5G device */ ++#define BCM4336_D11N_ID 0x4343 /* 4336 802.11n 2.4GHz device */ ++#define BCM6362_D11N_ID 0x435f /* 6362 802.11n dualband device */ ++#define BCM4331_D11N_ID 0x4331 /* 4331 802.11n dualband id */ ++#define BCM4331_D11N2G_ID 0x4332 /* 4331 802.11n 2.4Ghz band id */ ++#define BCM4331_D11N5G_ID 0x4333 /* 4331 802.11n 5Ghz band id */ ++#define BCM43237_D11N_ID 0x4355 /* 43237 802.11n dualband device */ ++#define BCM43237_D11N5G_ID 0x4356 /* 43237 802.11n 5GHz device */ ++#define BCM43227_D11N2G_ID 0x4358 /* 43228 802.11n 2.4GHz device */ ++#define BCM43228_D11N_ID 0x4359 /* 43228 802.11n DualBand device */ ++#define BCM43228_D11N5G_ID 0x435a /* 43228 802.11n 5GHz device */ ++#define BCM43362_D11N_ID 0x4363 /* 43362 802.11n 2.4GHz device */ ++#define BCM43239_D11N_ID 0x4370 /* 43239 802.11n dualband device */ ++#define BCM4324_D11N_ID 0x4374 /* 4324 802.11n dualband device */ ++#define BCM43217_D11N2G_ID 0x43a9 /* 43217 802.11n 2.4GHz device */ ++#define BCM43131_D11N2G_ID 0x43aa /* 43131 802.11n 2.4GHz device */ ++#define BCM4314_D11N2G_ID 0x4364 /* 4314 802.11n 2.4G device */ ++#define BCM43142_D11N2G_ID 0x4365 /* 43142 802.11n 2.4G device */ ++#define BCM4334_D11N_ID 0x4380 /* 4334 802.11n dualband device */ ++#define BCM4334_D11N2G_ID 0x4381 /* 4334 802.11n 2.4G device */ ++#define BCM4334_D11N5G_ID 0x4382 /* 4334 802.11n 5G device */ ++#define BCM4360_D11AC_ID 0x43a0 ++#define BCM4360_D11AC2G_ID 0x43a1 ++#define BCM4360_D11AC5G_ID 0x43a2 ++#define BCM4335_D11AC_ID 0x43ae ++#define BCM4335_D11AC2G_ID 0x43af ++#define BCM4335_D11AC5G_ID 0x43b0 ++#define BCM4352_D11AC_ID 0x43b1 /* 4352 802.11ac dualband device */ ++#define BCM4352_D11AC2G_ID 0x43b2 /* 4352 802.11ac 2.4G device */ ++#define BCM4352_D11AC5G_ID 0x43b3 /* 4352 802.11ac 5G device */ ++ ++/* PCI Subsystem ID */ ++#define BCM943228HMB_SSID_VEN1 0x0607 ++#define BCM94313HMGBL_SSID_VEN1 0x0608 ++#define BCM94313HMG_SSID_VEN1 0x0609 ++ ++ ++#define BCMGPRS_UART_ID 0x4333 /* Uart id used by 4306/gprs card */ ++#define BCMGPRS2_UART_ID 0x4344 /* Uart id used by 4306/gprs card */ ++#define FPGA_JTAGM_ID 0x43f0 /* FPGA jtagm device id */ ++#define BCM_JTAGM_ID 0x43f1 /* BCM jtagm device id */ ++#define SDIOH_FPGA_ID 0x43f2 /* sdio host fpga */ ++#define BCM_SDIOH_ID 0x43f3 /* BCM sdio host id */ ++#define SDIOD_FPGA_ID 0x43f4 /* sdio device fpga */ ++#define SPIH_FPGA_ID 0x43f5 /* PCI SPI Host Controller FPGA */ ++#define BCM_SPIH_ID 0x43f6 /* Synopsis SPI Host Controller */ ++#define MIMO_FPGA_ID 0x43f8 /* FPGA mimo minimacphy device id */ ++#define BCM_JTAGM2_ID 0x43f9 /* BCM alternate jtagm device id */ ++#define SDHCI_FPGA_ID 0x43fa /* Standard SDIO Host Controller FPGA */ ++#define BCM4402_ENET_ID 0x4402 /* 4402 enet */ ++#define BCM4402_V90_ID 0x4403 /* 4402 v90 codec */ ++#define BCM4410_DEVICE_ID 0x4410 /* bcm44xx family pci iline */ ++#define BCM4412_DEVICE_ID 0x4412 /* bcm44xx family pci enet */ ++#define BCM4430_DEVICE_ID 0x4430 /* bcm44xx family cardbus iline */ ++#define BCM4432_DEVICE_ID 0x4432 /* bcm44xx family cardbus enet */ ++#define BCM4704_ENET_ID 0x4706 /* 4704 enet (Use 47XX_ENET_ID instead!) */ ++#define BCM4710_DEVICE_ID 0x4710 /* 4710 primary function 0 */ ++#define BCM47XX_AUDIO_ID 0x4711 /* 47xx audio codec */ ++#define BCM47XX_V90_ID 0x4712 /* 47xx v90 codec */ ++#define BCM47XX_ENET_ID 0x4713 /* 47xx enet */ ++#define BCM47XX_EXT_ID 0x4714 /* 47xx external i/f */ ++#define BCM47XX_GMAC_ID 0x4715 /* 47xx Unimac based GbE */ ++#define BCM47XX_USBH_ID 0x4716 /* 47xx usb host */ ++#define BCM47XX_USBD_ID 0x4717 /* 47xx usb device */ ++#define BCM47XX_IPSEC_ID 0x4718 /* 47xx ipsec */ ++#define BCM47XX_ROBO_ID 0x4719 /* 47xx/53xx roboswitch core */ ++#define BCM47XX_USB20H_ID 0x471a /* 47xx usb 2.0 host */ ++#define BCM47XX_USB20D_ID 0x471b /* 47xx usb 2.0 device */ ++#define BCM47XX_ATA100_ID 0x471d /* 47xx parallel ATA */ ++#define BCM47XX_SATAXOR_ID 0x471e /* 47xx serial ATA & XOR DMA */ ++#define BCM47XX_GIGETH_ID 0x471f /* 47xx GbE (5700) */ ++#define BCM4712_MIPS_ID 0x4720 /* 4712 base devid */ ++#define BCM4716_DEVICE_ID 0x4722 /* 4716 base devid */ ++#define BCM47XX_SMBUS_EMU_ID 0x47fe /* 47xx emulated SMBus device */ ++#define BCM47XX_XOR_EMU_ID 0x47ff /* 47xx emulated XOR engine */ ++#define EPI41210_DEVICE_ID 0xa0fa /* bcm4210 */ ++#define EPI41230_DEVICE_ID 0xa10e /* bcm4230 */ ++#define JINVANI_SDIOH_ID 0x4743 /* Jinvani SDIO Gold Host */ ++#define BCM27XX_SDIOH_ID 0x2702 /* BCM27xx Standard SDIO Host */ ++#define PCIXX21_FLASHMEDIA_ID 0x803b /* TI PCI xx21 Standard Host Controller */ ++#define PCIXX21_SDIOH_ID 0x803c /* TI PCI xx21 Standard Host Controller */ ++#define R5C822_SDIOH_ID 0x0822 /* Ricoh Co Ltd R5C822 SD/SDIO/MMC/MS/MSPro Host */ ++#define JMICRON_SDIOH_ID 0x2381 /* JMicron Standard SDIO Host Controller */ ++ ++/* Chip IDs */ ++#define BCM4306_CHIP_ID 0x4306 /* 4306 chipcommon chipid */ ++#define BCM4311_CHIP_ID 0x4311 /* 4311 PCIe 802.11a/b/g */ ++#define BCM43111_CHIP_ID 43111 /* 43111 chipcommon chipid (OTP chipid) */ ++#define BCM43112_CHIP_ID 43112 /* 43112 chipcommon chipid (OTP chipid) */ ++#define BCM4312_CHIP_ID 0x4312 /* 4312 chipcommon chipid */ ++#define BCM4313_CHIP_ID 0x4313 /* 4313 chip id */ ++#define BCM43131_CHIP_ID 43131 /* 43131 chip id (OTP chipid) */ ++#define BCM4315_CHIP_ID 0x4315 /* 4315 chip id */ ++#define BCM4318_CHIP_ID 0x4318 /* 4318 chipcommon chipid */ ++#define BCM4319_CHIP_ID 0x4319 /* 4319 chip id */ ++#define BCM4320_CHIP_ID 0x4320 /* 4320 chipcommon chipid */ ++#define BCM4321_CHIP_ID 0x4321 /* 4321 chipcommon chipid */ ++#define BCM43217_CHIP_ID 43217 /* 43217 chip id (OTP chipid) */ ++#define BCM4322_CHIP_ID 0x4322 /* 4322 chipcommon chipid */ ++#define BCM43221_CHIP_ID 43221 /* 43221 chipcommon chipid (OTP chipid) */ ++#define BCM43222_CHIP_ID 43222 /* 43222 chipcommon chipid */ ++#define BCM43224_CHIP_ID 43224 /* 43224 chipcommon chipid */ ++#define BCM43225_CHIP_ID 43225 /* 43225 chipcommon chipid */ ++#define BCM43227_CHIP_ID 43227 /* 43227 chipcommon chipid */ ++#define BCM43228_CHIP_ID 43228 /* 43228 chipcommon chipid */ ++#define BCM43226_CHIP_ID 43226 /* 43226 chipcommon chipid */ ++#define BCM43231_CHIP_ID 43231 /* 43231 chipcommon chipid (OTP chipid) */ ++#define BCM43234_CHIP_ID 43234 /* 43234 chipcommon chipid */ ++#define BCM43235_CHIP_ID 43235 /* 43235 chipcommon chipid */ ++#define BCM43236_CHIP_ID 43236 /* 43236 chipcommon chipid */ ++#define BCM43237_CHIP_ID 43237 /* 43237 chipcommon chipid */ ++#define BCM43238_CHIP_ID 43238 /* 43238 chipcommon chipid */ ++#define BCM43239_CHIP_ID 43239 /* 43239 chipcommon chipid */ ++#define BCM43420_CHIP_ID 43420 /* 43222 chipcommon chipid (OTP, RBBU) */ ++#define BCM43421_CHIP_ID 43421 /* 43224 chipcommon chipid (OTP, RBBU) */ ++#define BCM43428_CHIP_ID 43428 /* 43228 chipcommon chipid (OTP, RBBU) */ ++#define BCM43431_CHIP_ID 43431 /* 4331 chipcommon chipid (OTP, RBBU) */ ++#define BCM43460_CHIP_ID 43460 /* 4360 chipcommon chipid (OTP, RBBU) */ ++#define BCM4325_CHIP_ID 0x4325 /* 4325 chip id */ ++#define BCM4328_CHIP_ID 0x4328 /* 4328 chip id */ ++#define BCM4329_CHIP_ID 0x4329 /* 4329 chipcommon chipid */ ++#define BCM4331_CHIP_ID 0x4331 /* 4331 chipcommon chipid */ ++#define BCM4336_CHIP_ID 0x4336 /* 4336 chipcommon chipid */ ++#define BCM43362_CHIP_ID 43362 /* 43362 chipcommon chipid */ ++#define BCM4330_CHIP_ID 0x4330 /* 4330 chipcommon chipid */ ++#define BCM6362_CHIP_ID 0x6362 /* 6362 chipcommon chipid */ ++#define BCM4314_CHIP_ID 0x4314 /* 4314 chipcommon chipid */ ++#define BCM43142_CHIP_ID 43142 /* 43142 chipcommon chipid */ ++#define BCM4324_CHIP_ID 0x4324 /* 4324 chipcommon chipid */ ++#define BCM43242_CHIP_ID 43242 /* 43242 chipcommon chipid */ ++#define BCM4334_CHIP_ID 0x4334 /* 4334 chipcommon chipid */ ++#define BCM4335_CHIP_ID 0x4335 ++#define BCM4360_CHIP_ID 0x4360 ++#define BCM43526_CHIP_ID 0xAA06 ++#define BCM4352_CHIP_ID 0x4352 ++ ++#define BCM4342_CHIP_ID 4342 /* 4342 chipcommon chipid (OTP, RBBU) */ ++#define BCM4402_CHIP_ID 0x4402 /* 4402 chipid */ ++#define BCM4704_CHIP_ID 0x4704 /* 4704 chipcommon chipid */ ++#define BCM4706_CHIP_ID 0x5300 /* 4706 chipcommon chipid */ ++#define BCM4710_CHIP_ID 0x4710 /* 4710 chipid */ ++#define BCM4712_CHIP_ID 0x4712 /* 4712 chipcommon chipid */ ++#define BCM4716_CHIP_ID 0x4716 /* 4716 chipcommon chipid */ ++#define BCM47162_CHIP_ID 47162 /* 47162 chipcommon chipid */ ++#define BCM4748_CHIP_ID 0x4748 /* 4716 chipcommon chipid (OTP, RBBU) */ ++#define BCM4749_CHIP_ID 0x4749 /* 5357 chipcommon chipid (OTP, RBBU) */ ++#define BCM4785_CHIP_ID 0x4785 /* 4785 chipcommon chipid */ ++#define BCM5350_CHIP_ID 0x5350 /* 5350 chipcommon chipid */ ++#define BCM5352_CHIP_ID 0x5352 /* 5352 chipcommon chipid */ ++#define BCM5354_CHIP_ID 0x5354 /* 5354 chipcommon chipid */ ++#define BCM5365_CHIP_ID 0x5365 /* 5365 chipcommon chipid */ ++#define BCM5356_CHIP_ID 0x5356 /* 5356 chipcommon chipid */ ++#define BCM5357_CHIP_ID 0x5357 /* 5357 chipcommon chipid */ ++#define BCM53572_CHIP_ID 53572 /* 53572 chipcommon chipid */ ++#define BCM53010_CHIP_ID 53010 /* NS chipcommon chipid */ ++#define BCM56150_CHIP_ID 56150 /* HR2 chipcommon chipid */ ++#define BCM56340_CHIP_ID 56340 /* HX4 chipcommon chipid */ ++#define BCM53020_CHIP_ID 53020 /* NSP chipcommon chipid */ ++#define BCM56450_CHIP_ID 56450 /* KT2 chipcommon chipid */ ++#define BCM54016_CHIP_ID 54016 /* CYGNUS chipcommon chipid */ ++#define BCM53400_CHIP_ID 0x8416 /* GH chipcommon chipid */ ++#define BCM56260_CHIP_ID 0xb260 /* SB2 chipcommon chipid */ ++#define BCM56160_CHIP_ID 0xb160 /* HR3 chipcommon chipid */ ++#define BCM56170_CHIP_ID 0xb170 /* GH2 chipcommon chipid */ ++#define BCM53540_CHIP_ID 0x8540 /* WF2 chipcommon chipid */ ++ ++#if defined(CONFIG_MACH_HX4) ++#define BCMIPROC_CHIP_ID BCM56340_CHIP_ID ++#elif defined(CONFIG_MACH_HR2) ++#define BCMIPROC_CHIP_ID BCM56150_CHIP_ID ++#elif defined(CONFIG_MACH_KT2) ++#define BCMIPROC_CHIP_ID BCM56450_CHIP_ID ++#elif defined(CONFIG_MACH_GH) ++#define BCMIPROC_CHIP_ID BCM53400_CHIP_ID ++#elif defined(CONFIG_MACH_SB2) ++#define BCMIPROC_CHIP_ID BCM56260_CHIP_ID ++#elif defined(CONFIG_MACH_HR3) ++ ++#if defined(CONFIG_MACH_WH2) ++#define BCMIPROC_CHIP_ID BCM53540_CHIP_ID ++#else ++#define BCMIPROC_CHIP_ID BCM56160_CHIP_ID ++#endif ++ ++#elif defined(CONFIG_MACH_GH2) ++#define BCMIPROC_CHIP_ID BCM56170_CHIP_ID ++#endif ++ ++/* Package IDs */ ++#define BCM4303_PKG_ID 2 /* 4303 package id */ ++#define BCM4309_PKG_ID 1 /* 4309 package id */ ++#define BCM4712LARGE_PKG_ID 0 /* 340pin 4712 package id */ ++#define BCM4712SMALL_PKG_ID 1 /* 200pin 4712 package id */ ++#define BCM4712MID_PKG_ID 2 /* 225pin 4712 package id */ ++#define BCM4328USBD11G_PKG_ID 2 /* 4328 802.11g USB package id */ ++#define BCM4328USBDUAL_PKG_ID 3 /* 4328 802.11a/g USB package id */ ++#define BCM4328SDIOD11G_PKG_ID 4 /* 4328 802.11g SDIO package id */ ++#define BCM4328SDIODUAL_PKG_ID 5 /* 4328 802.11a/g SDIO package id */ ++#define BCM4329_289PIN_PKG_ID 0 /* 4329 289-pin package id */ ++#define BCM4329_182PIN_PKG_ID 1 /* 4329N 182-pin package id */ ++#define BCM5354E_PKG_ID 1 /* 5354E package id */ ++#define BCM4716_PKG_ID 8 /* 4716 package id */ ++#define BCM4717_PKG_ID 9 /* 4717 package id */ ++#define BCM4718_PKG_ID 10 /* 4718 package id */ ++#define BCM5356_PKG_NONMODE 1 /* 5356 package without nmode suppport */ ++#define BCM5358U_PKG_ID 8 /* 5358U package id */ ++#define BCM5358_PKG_ID 9 /* 5358 package id */ ++#define BCM47186_PKG_ID 10 /* 47186 package id */ ++#define BCM5357_PKG_ID 11 /* 5357 package id */ ++#define BCM5356U_PKG_ID 12 /* 5356U package id */ ++#define BCM53572_PKG_ID 8 /* 53572 package id */ ++#define BCM5357C0_PKG_ID 8 /* 5357c0 package id (the same as 53572) */ ++#define BCM47188_PKG_ID 9 /* 47188 package id */ ++#define BCM5358C0_PKG_ID 0xa /* 5358c0 package id */ ++#define BCM5356C0_PKG_ID 0xb /* 5356c0 package id */ ++#define BCM4331TT_PKG_ID 8 /* 4331 12x12 package id */ ++#define BCM4331TN_PKG_ID 9 /* 4331 12x9 package id */ ++#define BCM4331TNA0_PKG_ID 0xb /* 4331 12x9 package id */ ++#define BCM4706L_PKG_ID 1 /* 4706L package id */ ++ ++#define HDLSIM5350_PKG_ID 1 /* HDL simulator package id for a 5350 */ ++#define HDLSIM_PKG_ID 14 /* HDL simulator package id */ ++#define HWSIM_PKG_ID 15 /* Hardware simulator package id */ ++#define BCM43224_FAB_CSM 0x8 /* the chip is manufactured by CSM */ ++#define BCM43224_FAB_SMIC 0xa /* the chip is manufactured by SMIC */ ++#define BCM4336_WLBGA_PKG_ID 0x8 ++#define BCM4330_WLBGA_PKG_ID 0x0 ++#define BCM4314PCIE_ARM_PKG_ID (8 | 0) /* 4314 QFN PCI package id, bit 3 tie high */ ++#define BCM4314SDIO_PKG_ID (8 | 1) /* 4314 QFN SDIO package id */ ++#define BCM4314PCIE_PKG_ID (8 | 2) /* 4314 QFN PCI (ARM-less) package id */ ++#define BCM4314SDIO_ARM_PKG_ID (8 | 3) /* 4314 QFN SDIO (ARM-less) package id */ ++#define BCM4314SDIO_FPBGA_PKG_ID (8 | 4) /* 4314 FpBGA SDIO package id */ ++#define BCM4314DEV_PKG_ID (8 | 6) /* 4314 Developement package id */ ++ ++#define BCM4707_PKG_ID 1 /* 4707 package id */ ++#define BCM4708_PKG_ID 2 /* 4708 package id */ ++#define BCM4709_PKG_ID 0 /* 4709 package id */ ++ ++#define PCIXX21_FLASHMEDIA0_ID 0x8033 /* TI PCI xx21 Standard Host Controller */ ++#define PCIXX21_SDIOH0_ID 0x8034 /* TI PCI xx21 Standard Host Controller */ ++ ++#define BCM4335_WLCSP_PKG_ID (0x0) /* WLCSP Module/Mobile SDIO/HSIC. */ ++#define BCM4335_FCBGA_PKG_ID (0x1) /* FCBGA PC/Embeded/Media PCIE/SDIO */ ++#define BCM4335_WLBGA_PKG_ID (0x2) /* WLBGA COB/Mobile SDIO/HSIC. */ ++#define BCM4335_FCBGAD_PKG_ID (0x3) /* FCBGA Debug Debug/Dev All if's. */ ++#define BCM4335_PKG_MASK (0x3) ++ ++/* boardflags */ ++#define BFL_BTC2WIRE 0x00000001 /* old 2wire Bluetooth coexistence, OBSOLETE */ ++#define BFL_BTCOEX 0x00000001 /* Board supports BTCOEX */ ++#define BFL_PACTRL 0x00000002 /* Board has gpio 9 controlling the PA */ ++#define BFL_AIRLINEMODE 0x00000004 /* Board implements gpio 13 radio disable indication, UNUSED */ ++#define BFL_ADCDIV 0x00000008 /* Board has the rssi ADC divider */ ++#define BFL_ENETROBO 0x00000010 /* Board has robo switch or core */ ++#define BFL_NOPLLDOWN 0x00000020 /* Not ok to power down the chip pll and oscillator */ ++#define BFL_CCKHIPWR 0x00000040 /* Can do high-power CCK transmission */ ++#define BFL_ENETADM 0x00000080 /* Board has ADMtek switch */ ++#define BFL_ENETVLAN 0x00000100 /* Board has VLAN capability */ ++#define BFL_UNUSED 0x00000200 ++#define BFL_NOPCI 0x00000400 /* Board leaves PCI floating */ ++#define BFL_FEM 0x00000800 /* Board supports the Front End Module */ ++#define BFL_EXTLNA 0x00001000 /* Board has an external LNA in 2.4GHz band */ ++#define BFL_HGPA 0x00002000 /* Board has a high gain PA */ ++#define BFL_BTC2WIRE_ALTGPIO 0x00004000 /* Board's BTC 2wire is in the alternate gpios */ ++#define BFL_ALTIQ 0x00008000 /* Alternate I/Q settings */ ++#define BFL_NOPA 0x00010000 /* Board has no PA */ ++#define BFL_RSSIINV 0x00020000 /* Board's RSSI uses positive slope(not TSSI) */ ++#define BFL_PAREF 0x00040000 /* Board uses the PARef LDO */ ++#define BFL_3TSWITCH 0x00080000 /* Board uses a triple throw switch shared with BT */ ++#define BFL_PHASESHIFT 0x00100000 /* Board can support phase shifter */ ++#define BFL_BUCKBOOST 0x00200000 /* Power topology uses BUCKBOOST */ ++#define BFL_FEM_BT 0x00400000 /* Board has FEM and switch to share antenna w/ BT */ ++#define BFL_NOCBUCK 0x00800000 /* Power topology doesn't use CBUCK */ ++#define BFL_CCKFAVOREVM 0x01000000 /* Favor CCK EVM over spectral mask */ ++#define BFL_PALDO 0x02000000 /* Power topology uses PALDO */ ++#define BFL_LNLDO2_2P5 0x04000000 /* Select 2.5V as LNLDO2 output voltage */ ++#define BFL_FASTPWR 0x08000000 ++#define BFL_UCPWRCTL_MININDX 0x08000000 /* Enforce min power index to avoid FEM damage */ ++#define BFL_EXTLNA_5GHz 0x10000000 /* Board has an external LNA in 5GHz band */ ++#define BFL_TRSW_1by2 0x20000000 /* Board has 2 TRSW's in 1by2 designs */ ++#define BFL_LO_TRSW_R_5GHz 0x40000000 /* In 5G do not throw TRSW to T for clipLO gain */ ++#define BFL_ELNA_GAINDEF 0x80000000 /* Backoff InitGain based on elna_2g/5g field ++ * when this flag is set ++ */ ++#define BFL_EXTLNA_TX 0x20000000 /* Temp boardflag to indicate to */ ++ ++/* boardflags2 */ ++#define BFL2_RXBB_INT_REG_DIS 0x00000001 /* Board has an external rxbb regulator */ ++#define BFL2_APLL_WAR 0x00000002 /* Flag to implement alternative A-band PLL settings */ ++#define BFL2_TXPWRCTRL_EN 0x00000004 /* Board permits enabling TX Power Control */ ++#define BFL2_2X4_DIV 0x00000008 /* Board supports the 2X4 diversity switch */ ++#define BFL2_5G_PWRGAIN 0x00000010 /* Board supports 5G band power gain */ ++#define BFL2_PCIEWAR_OVR 0x00000020 /* Board overrides ASPM and Clkreq settings */ ++#define BFL2_CAESERS_BRD 0x00000040 /* Board is Caesers brd (unused by sw) */ ++#define BFL2_BTC3WIRE 0x00000080 /* Board support legacy 3 wire or 4 wire */ ++#define BFL2_BTCLEGACY 0x00000080 /* Board support legacy 3/4 wire, to replace ++ * BFL2_BTC3WIRE ++ */ ++#define BFL2_SKWRKFEM_BRD 0x00000100 /* 4321mcm93 board uses Skyworks FEM */ ++#define BFL2_SPUR_WAR 0x00000200 /* Board has a WAR for clock-harmonic spurs */ ++#define BFL2_GPLL_WAR 0x00000400 /* Flag to narrow G-band PLL loop b/w */ ++#define BFL2_TRISTATE_LED 0x00000800 /* Tri-state the LED */ ++#define BFL2_SINGLEANT_CCK 0x00001000 /* Tx CCK pkts on Ant 0 only */ ++#define BFL2_2G_SPUR_WAR 0x00002000 /* WAR to reduce and avoid clock-harmonic spurs in 2G */ ++#define BFL2_BPHY_ALL_TXCORES 0x00004000 /* Transmit bphy frames using all tx cores */ ++#define BFL2_FCC_BANDEDGE_WAR 0x00008000 /* Activates WAR to improve FCC bandedge performance */ ++#define BFL2_GPLL_WAR2 0x00010000 /* Flag to widen G-band PLL loop b/w */ ++#define BFL2_IPALVLSHIFT_3P3 0x00020000 ++#define BFL2_INTERNDET_TXIQCAL 0x00040000 /* Use internal envelope detector for TX IQCAL */ ++#define BFL2_XTALBUFOUTEN 0x00080000 /* Keep the buffered Xtal output from radio on */ ++ /* Most drivers will turn it off without this flag */ ++ /* to save power. */ ++ ++#define BFL2_ANAPACTRL_2G 0x00100000 /* 2G ext PAs are controlled by analog PA ctrl lines */ ++#define BFL2_ANAPACTRL_5G 0x00200000 /* 5G ext PAs are controlled by analog PA ctrl lines */ ++#define BFL2_ELNACTRL_TRSW_2G 0x00400000 /* AZW4329: 2G gmode_elna_gain controls TR Switch */ ++#define BFL2_BT_SHARE_ANT0 0x00800000 /* share core0 antenna with BT */ ++#define BFL2_TEMPSENSE_HIGHER 0x01000000 /* The tempsense threshold can sustain higher value ++ * than programmed. The exact delta is decided by ++ * driver per chip/boardtype. This can be used ++ * when tempsense qualification happens after shipment ++ */ ++#define BFL2_BTC3WIREONLY 0x02000000 /* standard 3 wire btc only. 4 wire not supported */ ++#define BFL2_PWR_NOMINAL 0x04000000 /* 0: power reduction on, 1: no power reduction */ ++#define BFL2_EXTLNA_PWRSAVE 0x08000000 /* boardflag to enable ucode to apply power save */ ++ /* ucode control of eLNA during Tx */ ++#define BFL2_4313_RADIOREG 0x10000000 ++ /* board rework */ ++#define BFL2_SDR_EN 0x20000000 /* SDR enabled or disabled */ ++ ++/* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */ ++#define BOARD_GPIO_BTC3W_IN 0x850 /* bit 4 is RF_ACTIVE, bit 6 is STATUS, bit 11 is PRI */ ++#define BOARD_GPIO_BTC3W_OUT 0x020 /* bit 5 is TX_CONF */ ++#define BOARD_GPIO_BTCMOD_IN 0x010 /* bit 4 is the alternate BT Coexistence Input */ ++#define BOARD_GPIO_BTCMOD_OUT 0x020 /* bit 5 is the alternate BT Coexistence Out */ ++#define BOARD_GPIO_BTC_IN 0x080 /* bit 7 is BT Coexistence Input */ ++#define BOARD_GPIO_BTC_OUT 0x100 /* bit 8 is BT Coexistence Out */ ++#define BOARD_GPIO_PACTRL 0x200 /* bit 9 controls the PA on new 4306 boards */ ++#define BOARD_GPIO_12 0x1000 /* gpio 12 */ ++#define BOARD_GPIO_13 0x2000 /* gpio 13 */ ++#define BOARD_GPIO_BTC4_IN 0x0800 /* gpio 11, coex4, in */ ++#define BOARD_GPIO_BTC4_BT 0x2000 /* gpio 12, coex4, bt active */ ++#define BOARD_GPIO_BTC4_STAT 0x4000 /* gpio 14, coex4, status */ ++#define BOARD_GPIO_BTC4_WLAN 0x8000 /* gpio 15, coex4, wlan active */ ++#define BOARD_GPIO_1_WLAN_PWR 0x02 /* throttle WLAN power on X21 board */ ++#define BOARD_GPIO_3_WLAN_PWR 0x08 /* throttle WLAN power on X28 board */ ++#define BOARD_GPIO_4_WLAN_PWR 0x10 /* throttle WLAN power on X19 board */ ++ ++#define GPIO_BTC4W_OUT_4312 0x010 /* bit 4 is BT_IODISABLE */ ++#define GPIO_BTC4W_OUT_43224 0x020 /* bit 5 is BT_IODISABLE */ ++#define GPIO_BTC4W_OUT_43224_SHARED 0x0e0 /* bit 5 is BT_IODISABLE */ ++#define GPIO_BTC4W_OUT_43225 0x0e0 /* bit 5 BT_IODISABLE, bit 6 SW_BT, bit 7 SW_WL */ ++#define GPIO_BTC4W_OUT_43421 0x020 /* bit 5 is BT_IODISABLE */ ++#define GPIO_BTC4W_OUT_4313 0x060 /* bit 5 SW_BT, bit 6 SW_WL */ ++#define GPIO_BTC4W_OUT_4331_SHARED 0x010 /* GPIO 4 */ ++ ++#define PCI_CFG_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */ ++#define PCI_CFG_GPIO_HWRAD 0x20 /* PCI config space GPIO 13 for hw radio disable */ ++#define PCI_CFG_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal power-up */ ++#define PCI_CFG_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL power-down */ ++ ++/* power control defines */ ++#define PLL_DELAY 150 /* us pll on delay */ ++#define FREF_DELAY 200 /* us fref change delay */ ++#define MIN_SLOW_CLK 32 /* us Slow clock period */ ++#define XTAL_ON_DELAY 1000 /* us crystal power-on delay */ ++ ++#ifndef LINUX_POSTMOGRIFY_REMOVAL ++/* Reference Board Types */ ++#define BU4710_BOARD 0x0400 ++#define VSIM4710_BOARD 0x0401 ++#define QT4710_BOARD 0x0402 ++ ++#define BU4309_BOARD 0x040a ++#define BCM94309CB_BOARD 0x040b ++#define BCM94309MP_BOARD 0x040c ++#define BCM4309AP_BOARD 0x040d ++ ++#define BCM94302MP_BOARD 0x040e ++ ++#define BU4306_BOARD 0x0416 ++#define BCM94306CB_BOARD 0x0417 ++#define BCM94306MP_BOARD 0x0418 ++ ++#define BCM94710D_BOARD 0x041a ++#define BCM94710R1_BOARD 0x041b ++#define BCM94710R4_BOARD 0x041c ++#define BCM94710AP_BOARD 0x041d ++ ++#define BU2050_BOARD 0x041f ++ ++#define BCM94306P50_BOARD 0x0420 ++ ++#define BCM94309G_BOARD 0x0421 ++ ++#define BU4704_BOARD 0x0423 ++#define BU4702_BOARD 0x0424 ++ ++#define BCM94306PC_BOARD 0x0425 /* pcmcia 3.3v 4306 card */ ++ ++#define MPSG4306_BOARD 0x0427 ++ ++#define BCM94702MN_BOARD 0x0428 ++ ++/* BCM4702 1U CompactPCI Board */ ++#define BCM94702CPCI_BOARD 0x0429 ++ ++/* BCM4702 with BCM95380 VLAN Router */ ++#define BCM95380RR_BOARD 0x042a ++ ++/* cb4306 with SiGe PA */ ++#define BCM94306CBSG_BOARD 0x042b ++ ++/* cb4306 with SiGe PA */ ++#define PCSG94306_BOARD 0x042d ++ ++/* bu4704 with sdram */ ++#define BU4704SD_BOARD 0x042e ++ ++/* Dual 11a/11g Router */ ++#define BCM94704AGR_BOARD 0x042f ++ ++/* 11a-only minipci */ ++#define BCM94308MP_BOARD 0x0430 ++ ++/* 4306/gprs combo */ ++#define BCM94306GPRS_BOARD 0x0432 ++ ++/* BCM5365/BCM4704 FPGA Bringup Board */ ++#define BU5365_FPGA_BOARD 0x0433 ++ ++#define BU4712_BOARD 0x0444 ++#define BU4712SD_BOARD 0x045d ++#define BU4712L_BOARD 0x045f ++ ++/* BCM4712 boards */ ++#define BCM94712AP_BOARD 0x0445 ++#define BCM94712P_BOARD 0x0446 ++ ++/* BCM4318 boards */ ++#define BU4318_BOARD 0x0447 ++#define CB4318_BOARD 0x0448 ++#define MPG4318_BOARD 0x0449 ++#define MP4318_BOARD 0x044a ++#define SD4318_BOARD 0x044b ++ ++/* BCM4313 boards */ ++#define BCM94313BU_BOARD 0x050f ++#define BCM94313HM_BOARD 0x0510 ++#define BCM94313EPA_BOARD 0x0511 ++#define BCM94313HMG_BOARD 0x051C ++ ++/* BCM63XX boards */ ++#define BCM96338_BOARD 0x6338 ++#define BCM96348_BOARD 0x6348 ++#define BCM96358_BOARD 0x6358 ++#define BCM96368_BOARD 0x6368 ++ ++/* Another mp4306 with SiGe */ ++#define BCM94306P_BOARD 0x044c ++ ++/* mp4303 */ ++#define BCM94303MP_BOARD 0x044e ++ ++/* mpsgh4306 */ ++#define BCM94306MPSGH_BOARD 0x044f ++ ++/* BRCM 4306 w/ Front End Modules */ ++#define BCM94306MPM 0x0450 ++#define BCM94306MPL 0x0453 ++ ++/* 4712agr */ ++#define BCM94712AGR_BOARD 0x0451 ++ ++/* pcmcia 4303 */ ++#define PC4303_BOARD 0x0454 ++ ++/* 5350K */ ++#define BCM95350K_BOARD 0x0455 ++ ++/* 5350R */ ++#define BCM95350R_BOARD 0x0456 ++ ++/* 4306mplna */ ++#define BCM94306MPLNA_BOARD 0x0457 ++ ++/* 4320 boards */ ++#define BU4320_BOARD 0x0458 ++#define BU4320S_BOARD 0x0459 ++#define BCM94320PH_BOARD 0x045a ++ ++/* 4306mph */ ++#define BCM94306MPH_BOARD 0x045b ++ ++/* 4306pciv */ ++#define BCM94306PCIV_BOARD 0x045c ++ ++#define BU4712SD_BOARD 0x045d ++ ++#define BCM94320PFLSH_BOARD 0x045e ++ ++#define BU4712L_BOARD 0x045f ++#define BCM94712LGR_BOARD 0x0460 ++#define BCM94320R_BOARD 0x0461 ++ ++#define BU5352_BOARD 0x0462 ++ ++#define BCM94318MPGH_BOARD 0x0463 ++ ++#define BU4311_BOARD 0x0464 ++#define BCM94311MC_BOARD 0x0465 ++#define BCM94311MCAG_BOARD 0x0466 ++ ++#define BCM95352GR_BOARD 0x0467 ++ ++/* bcm95351agr */ ++#define BCM95351AGR_BOARD 0x0470 ++ ++/* bcm94704mpcb */ ++#define BCM94704MPCB_BOARD 0x0472 ++ ++/* 4785 boards */ ++#define BU4785_BOARD 0x0478 ++ ++/* 4321 boards */ ++#define BU4321_BOARD 0x046b ++#define BU4321E_BOARD 0x047c ++#define MP4321_BOARD 0x046c ++#define CB2_4321_BOARD 0x046d ++#define CB2_4321_AG_BOARD 0x0066 ++#define MC4321_BOARD 0x046e ++ ++/* 4328 boards */ ++#define BU4328_BOARD 0x0481 ++#define BCM4328SDG_BOARD 0x0482 ++#define BCM4328SDAG_BOARD 0x0483 ++#define BCM4328UG_BOARD 0x0484 ++#define BCM4328UAG_BOARD 0x0485 ++#define BCM4328PC_BOARD 0x0486 ++#define BCM4328CF_BOARD 0x0487 ++ ++/* 4325 boards */ ++#define BCM94325DEVBU_BOARD 0x0490 ++#define BCM94325BGABU_BOARD 0x0491 ++ ++#define BCM94325SDGWB_BOARD 0x0492 ++ ++#define BCM94325SDGMDL_BOARD 0x04aa ++#define BCM94325SDGMDL2_BOARD 0x04c6 ++#define BCM94325SDGMDL3_BOARD 0x04c9 ++ ++#define BCM94325SDABGWBA_BOARD 0x04e1 ++ ++/* 4322 boards */ ++#define BCM94322MC_SSID 0x04a4 ++#define BCM94322USB_SSID 0x04a8 /* dualband */ ++#define BCM94322HM_SSID 0x04b0 ++#define BCM94322USB2D_SSID 0x04bf /* single band discrete front end */ ++ ++/* 4312 boards */ ++#define BCM4312MCGSG_BOARD 0x04b5 ++ ++/* 4315 boards */ ++#define BCM94315DEVBU_SSID 0x04c2 ++#define BCM94315USBGP_SSID 0x04c7 ++#define BCM94315BGABU_SSID 0x04ca ++#define BCM94315USBGP41_SSID 0x04cb ++ ++/* 4319 boards */ ++#define BCM94319DEVBU_SSID 0X04e5 ++#define BCM94319USB_SSID 0X04e6 ++#define BCM94319SD_SSID 0X04e7 ++ ++/* 4716 boards */ ++#define BCM94716NR2_SSID 0x04cd ++ ++/* 4319 boards */ ++#define BCM94319DEVBU_SSID 0X04e5 ++#define BCM94319USBNP4L_SSID 0X04e6 ++#define BCM94319WLUSBN4L_SSID 0X04e7 ++#define BCM94319SDG_SSID 0X04ea ++#define BCM94319LCUSBSDN4L_SSID 0X04eb ++#define BCM94319USBB_SSID 0x04ee ++#define BCM94319LCSDN4L_SSID 0X0507 ++#define BCM94319LSUSBN4L_SSID 0X0508 ++#define BCM94319SDNA4L_SSID 0X0517 ++#define BCM94319SDELNA4L_SSID 0X0518 ++#define BCM94319SDELNA6L_SSID 0X0539 ++#define BCM94319ARCADYAN_SSID 0X0546 ++#define BCM94319WINDSOR_SSID 0x0561 ++#define BCM94319MLAP_SSID 0x0562 ++#define BCM94319SDNA_SSID 0x058b ++#define BCM94319BHEMU3_SSID 0x0563 ++#define BCM94319SDHMB_SSID 0x058c ++#define BCM94319SDBREF_SSID 0x05a1 ++#define BCM94319USBSDB_SSID 0x05a2 ++ ++ ++/* 4329 boards */ ++#define BCM94329AGB_SSID 0X04b9 ++#define BCM94329TDKMDL1_SSID 0X04ba ++#define BCM94329TDKMDL11_SSID 0X04fc ++#define BCM94329OLYMPICN18_SSID 0X04fd ++#define BCM94329OLYMPICN90_SSID 0X04fe ++#define BCM94329OLYMPICN90U_SSID 0X050c ++#define BCM94329OLYMPICN90M_SSID 0X050b ++#define BCM94329AGBF_SSID 0X04ff ++#define BCM94329OLYMPICX17_SSID 0X0504 ++#define BCM94329OLYMPICX17M_SSID 0X050a ++#define BCM94329OLYMPICX17U_SSID 0X0509 ++#define BCM94329OLYMPICUNO_SSID 0X0564 ++#define BCM94329MOTOROLA_SSID 0X0565 ++#define BCM94329OLYMPICLOCO_SSID 0X0568 ++/* 4336 SDIO board types */ ++#define BCM94336SD_WLBGABU_SSID 0x0511 ++#define BCM94336SD_WLBGAREF_SSID 0x0519 ++#define BCM94336SDGP_SSID 0x0538 ++#define BCM94336SDG_SSID 0x0519 ++#define BCM94336SDGN_SSID 0x0538 ++#define BCM94336SDGFC_SSID 0x056B ++ ++/* 4330 SDIO board types */ ++#define BCM94330SDG_SSID 0x0528 ++#define BCM94330SD_FCBGABU_SSID 0x052e ++#define BCM94330SD_WLBGABU_SSID 0x052f ++#define BCM94330SD_FCBGA_SSID 0x0530 ++#define BCM94330FCSDAGB_SSID 0x0532 ++#define BCM94330OLYMPICAMG_SSID 0x0549 ++#define BCM94330OLYMPICAMGEPA_SSID 0x054F ++#define BCM94330OLYMPICUNO3_SSID 0x0551 ++#define BCM94330WLSDAGB_SSID 0x0547 ++#define BCM94330CSPSDAGBB_SSID 0x054A ++ ++/* 43224 boards */ ++#define BCM943224X21 0x056e ++#define BCM943224X21_FCC 0x00d1 ++#define BCM943224X21B 0x00e9 ++#define BCM943224M93 0x008b ++#define BCM943224M93A 0x0090 ++#define BCM943224X16 0x0093 ++#define BCM94322X9 0x008d ++#define BCM94322M35e 0x008e ++ ++/* 43228 Boards */ ++#define BCM943228BU8_SSID 0x0540 ++#define BCM943228BU9_SSID 0x0541 ++#define BCM943228BU_SSID 0x0542 ++#define BCM943227HM4L_SSID 0x0543 ++#define BCM943227HMB_SSID 0x0544 ++#define BCM943228HM4L_SSID 0x0545 ++#define BCM943228SD_SSID 0x0573 ++ ++/* 43239 Boards */ ++#define BCM943239MOD_SSID 0x05ac ++#define BCM943239REF_SSID 0x05aa ++ ++/* 4331 boards */ ++#define BCM94331X19 0x00D6 /* X19B */ ++#define BCM94331X28 0x00E4 /* X28 */ ++#define BCM94331X28B 0x010E /* X28B */ ++#define BCM94331PCIEBT3Ax_SSID BCM94331X28 ++#define BCM94331X12_2G_SSID 0x00EC /* X12 2G */ ++#define BCM94331X12_5G_SSID 0x00ED /* X12 5G */ ++#define BCM94331X29B 0x00EF /* X29B */ ++#define BCM94331CSAX_SSID BCM94331X29B ++#define BCM94331X19C 0x00F5 /* X19C */ ++#define BCM94331X33 0x00F4 /* X33 */ ++#define BCM94331BU_SSID 0x0523 ++#define BCM94331S9BU_SSID 0x0524 ++#define BCM94331MC_SSID 0x0525 ++#define BCM94331MCI_SSID 0x0526 ++#define BCM94331PCIEBT4_SSID 0x0527 ++#define BCM94331HM_SSID 0x0574 ++#define BCM94331PCIEDUAL_SSID 0x059B ++#define BCM94331MCH5_SSID 0x05A9 ++#define BCM94331CS_SSID 0x05C6 ++#define BCM94331CD_SSID 0x05DA ++ ++/* 4314 Boards */ ++#define BCM94314BU_SSID 0x05b1 ++ ++/* 53572 Boards */ ++#define BCM953572BU_SSID 0x058D ++#define BCM953572NR2_SSID 0x058E ++#define BCM947188NR2_SSID 0x058F ++#define BCM953572SDRNR2_SSID 0x0590 ++ ++/* 43236 boards */ ++#define BCM943236OLYMPICSULLEY_SSID 0x594 ++#define BCM943236PREPROTOBLU2O3_SSID 0x5b9 ++#define BCM943236USBELNA_SSID 0x5f8 ++ ++/* 4314 Boards */ ++#define BCM94314BUSDIO_SSID 0x05c8 ++#define BCM94314BGABU_SSID 0x05c9 ++#define BCM94314HMEPA_SSID 0x05ca ++#define BCM94314HMEPABK_SSID 0x05cb ++#define BCM94314SUHMEPA_SSID 0x05cc ++#define BCM94314SUHM_SSID 0x05cd ++#define BCM94314HM_SSID 0x05d1 ++ ++/* 4334 Boards */ ++#define BCM94334FCAGBI_SSID 0x05df ++#define BCM94334WLAGBI_SSID 0x05dd ++ ++/* 43217 Boards */ ++#define BCM943217BU_SSID 0x05d5 ++#define BCM943217HM2L_SSID 0x05d6 ++#define BCM943217HMITR2L_SSID 0x05d7 ++ ++/* 43142 Boards */ ++#define BCM943142HM_SSID 0x05e0 ++#endif /* LINUX_POSTMOGRIFY_REMOVAL */ ++ ++/* # of GPIO pins */ ++#define GPIO_NUMPINS 32 ++ ++/* These values are used by dhd host driver. */ ++#define RDL_RAM_BASE_4319 0x60000000 ++#define RDL_RAM_BASE_4329 0x60000000 ++#define RDL_RAM_SIZE_4319 0x48000 ++#define RDL_RAM_SIZE_4329 0x48000 ++#define RDL_RAM_SIZE_43236 0x70000 ++#define RDL_RAM_BASE_43236 0x60000000 ++#define RDL_RAM_SIZE_4328 0x60000 ++#define RDL_RAM_BASE_4328 0x80000000 ++#define RDL_RAM_SIZE_4322 0x60000 ++#define RDL_RAM_BASE_4322 0x60000000 ++#define RDL_RAM_SIZE_4360 0xE0000 ++#define RDL_RAM_BASE_4360 0x60000000 ++ ++/* generic defs for nvram "muxenab" bits ++* Note: these differ for 4335a0. refer bcmchipc.h for specific mux options. ++*/ ++#define MUXENAB_UART 0x00000001 ++#define MUXENAB_GPIO 0x00000002 ++#define MUXENAB_ERCX 0x00000004 ++#define MUXENAB_JTAG 0x00000008 ++#define MUXENAB_HOST_WAKE 0x00000010 ++ ++/* Boot flags */ ++#define FLASH_KERNEL_NFLASH 0x00000001 ++#define FLASH_BOOT_NFLASH 0x00000002 ++ ++#endif /* _BCMDEVS_H */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmendian.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmendian.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmendian.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmendian.h 2017-11-09 17:53:43.921293000 +0800 +@@ -0,0 +1,324 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Byte order utilities ++ * ++ * $Id: bcmendian.h 241182 2011-02-17 21:50:03Z $ ++ * ++ * This file by default provides proper behavior on little-endian architectures. ++ * On big-endian architectures, IL_BIGENDIAN should be defined. ++ */ ++ ++#ifndef _BCMENDIAN_H_ ++#define _BCMENDIAN_H_ ++ ++#include ++ ++/* Reverse the bytes in a 16-bit value */ ++#define BCMSWAP16(val) \ ++ ((uint16)((((uint16)(val) & (uint16)0x00ffU) << 8) | \ ++ (((uint16)(val) & (uint16)0xff00U) >> 8))) ++ ++/* Reverse the bytes in a 32-bit value */ ++#define BCMSWAP32(val) \ ++ ((uint32)((((uint32)(val) & (uint32)0x000000ffU) << 24) | \ ++ (((uint32)(val) & (uint32)0x0000ff00U) << 8) | \ ++ (((uint32)(val) & (uint32)0x00ff0000U) >> 8) | \ ++ (((uint32)(val) & (uint32)0xff000000U) >> 24))) ++ ++/* Reverse the two 16-bit halves of a 32-bit value */ ++#define BCMSWAP32BY16(val) \ ++ ((uint32)((((uint32)(val) & (uint32)0x0000ffffU) << 16) | \ ++ (((uint32)(val) & (uint32)0xffff0000U) >> 16))) ++ ++/* Byte swapping macros ++ * Host <=> Network (Big Endian) for 16- and 32-bit values ++ * Host <=> Little-Endian for 16- and 32-bit values ++ */ ++#ifndef hton16 ++#ifndef IL_BIGENDIAN ++#define HTON16(i) BCMSWAP16(i) ++#define hton16(i) bcmswap16(i) ++#define HTON32(i) BCMSWAP32(i) ++#define hton32(i) bcmswap32(i) ++#define NTOH16(i) BCMSWAP16(i) ++#define ntoh16(i) bcmswap16(i) ++#define NTOH32(i) BCMSWAP32(i) ++#define ntoh32(i) bcmswap32(i) ++#define LTOH16(i) (i) ++#define ltoh16(i) (i) ++#define LTOH32(i) (i) ++#define ltoh32(i) (i) ++#define HTOL16(i) (i) ++#define htol16(i) (i) ++#define HTOL32(i) (i) ++#define htol32(i) (i) ++#else /* IL_BIGENDIAN */ ++#define HTON16(i) (i) ++#define hton16(i) (i) ++#define HTON32(i) (i) ++#define hton32(i) (i) ++#define NTOH16(i) (i) ++#define ntoh16(i) (i) ++#define NTOH32(i) (i) ++#define ntoh32(i) (i) ++#define LTOH16(i) BCMSWAP16(i) ++#define ltoh16(i) bcmswap16(i) ++#define LTOH32(i) BCMSWAP32(i) ++#define ltoh32(i) bcmswap32(i) ++#define HTOL16(i) BCMSWAP16(i) ++#define htol16(i) bcmswap16(i) ++#define HTOL32(i) BCMSWAP32(i) ++#define htol32(i) bcmswap32(i) ++#endif /* IL_BIGENDIAN */ ++#endif /* hton16 */ ++ ++#ifndef IL_BIGENDIAN ++#define ltoh16_buf(buf, i) ++#define htol16_buf(buf, i) ++#else ++#define ltoh16_buf(buf, i) bcmswap16_buf((uint16 *)(buf), (i)) ++#define htol16_buf(buf, i) bcmswap16_buf((uint16 *)(buf), (i)) ++#endif /* IL_BIGENDIAN */ ++ ++/* Unaligned loads and stores in host byte order */ ++#ifndef IL_BIGENDIAN ++#define load32_ua(a) ltoh32_ua(a) ++#define store32_ua(a, v) htol32_ua_store(v, a) ++#define load16_ua(a) ltoh16_ua(a) ++#define store16_ua(a, v) htol16_ua_store(v, a) ++#else ++#define load32_ua(a) ntoh32_ua(a) ++#define store32_ua(a, v) hton32_ua_store(v, a) ++#define load16_ua(a) ntoh16_ua(a) ++#define store16_ua(a, v) hton16_ua_store(v, a) ++#endif /* IL_BIGENDIAN */ ++ ++#define _LTOH16_UA(cp) ((cp)[0] | ((cp)[1] << 8)) ++#define _LTOH32_UA(cp) ((cp)[0] | ((cp)[1] << 8) | ((cp)[2] << 16) | ((cp)[3] << 24)) ++#define _NTOH16_UA(cp) (((cp)[0] << 8) | (cp)[1]) ++#define _NTOH32_UA(cp) (((cp)[0] << 24) | ((cp)[1] << 16) | ((cp)[2] << 8) | (cp)[3]) ++ ++#define ltoh_ua(ptr) \ ++ (sizeof(*(ptr)) == sizeof(uint8) ? *(const uint8 *)(ptr) : \ ++ sizeof(*(ptr)) == sizeof(uint16) ? _LTOH16_UA((const uint8 *)(ptr)) : \ ++ sizeof(*(ptr)) == sizeof(uint32) ? _LTOH32_UA((const uint8 *)(ptr)) : \ ++ *(uint8 *)0) ++ ++#define ntoh_ua(ptr) \ ++ (sizeof(*(ptr)) == sizeof(uint8) ? *(const uint8 *)(ptr) : \ ++ sizeof(*(ptr)) == sizeof(uint16) ? _NTOH16_UA((const uint8 *)(ptr)) : \ ++ sizeof(*(ptr)) == sizeof(uint32) ? _NTOH32_UA((const uint8 *)(ptr)) : \ ++ *(uint8 *)0) ++ ++#ifdef __GNUC__ ++ ++/* GNU macro versions avoid referencing the argument multiple times, while also ++ * avoiding the -fno-inline used in ROM builds. ++ */ ++ ++#define bcmswap16(val) ({ \ ++ uint16 _val = (val); \ ++ BCMSWAP16(_val); \ ++}) ++ ++#define bcmswap32(val) ({ \ ++ uint32 _val = (val); \ ++ BCMSWAP32(_val); \ ++}) ++ ++#define bcmswap32by16(val) ({ \ ++ uint32 _val = (val); \ ++ BCMSWAP32BY16(_val); \ ++}) ++ ++#define bcmswap16_buf(buf, len) ({ \ ++ uint16 *_buf = (uint16 *)(buf); \ ++ uint _wds = (len) / 2; \ ++ while (_wds--) { \ ++ *_buf = bcmswap16(*_buf); \ ++ _buf++; \ ++ } \ ++}) ++ ++#define htol16_ua_store(val, bytes) ({ \ ++ uint16 _val = (val); \ ++ uint8 *_bytes = (uint8 *)(bytes); \ ++ _bytes[0] = _val & 0xff; \ ++ _bytes[1] = _val >> 8; \ ++}) ++ ++#define htol32_ua_store(val, bytes) ({ \ ++ uint32 _val = (val); \ ++ uint8 *_bytes = (uint8 *)(bytes); \ ++ _bytes[0] = _val & 0xff; \ ++ _bytes[1] = (_val >> 8) & 0xff; \ ++ _bytes[2] = (_val >> 16) & 0xff; \ ++ _bytes[3] = _val >> 24; \ ++}) ++ ++#define hton16_ua_store(val, bytes) ({ \ ++ uint16 _val = (val); \ ++ uint8 *_bytes = (uint8 *)(bytes); \ ++ _bytes[0] = _val >> 8; \ ++ _bytes[1] = _val & 0xff; \ ++}) ++ ++#define hton32_ua_store(val, bytes) ({ \ ++ uint32 _val = (val); \ ++ uint8 *_bytes = (uint8 *)(bytes); \ ++ _bytes[0] = _val >> 24; \ ++ _bytes[1] = (_val >> 16) & 0xff; \ ++ _bytes[2] = (_val >> 8) & 0xff; \ ++ _bytes[3] = _val & 0xff; \ ++}) ++ ++#define ltoh16_ua(bytes) ({ \ ++ const uint8 *_bytes = (const uint8 *)(bytes); \ ++ _LTOH16_UA(_bytes); \ ++}) ++ ++#define ltoh32_ua(bytes) ({ \ ++ const uint8 *_bytes = (const uint8 *)(bytes); \ ++ _LTOH32_UA(_bytes); \ ++}) ++ ++#define ntoh16_ua(bytes) ({ \ ++ const uint8 *_bytes = (const uint8 *)(bytes); \ ++ _NTOH16_UA(_bytes); \ ++}) ++ ++#define ntoh32_ua(bytes) ({ \ ++ const uint8 *_bytes = (const uint8 *)(bytes); \ ++ _NTOH32_UA(_bytes); \ ++}) ++ ++#else /* !__GNUC__ */ ++ ++/* Inline versions avoid referencing the argument multiple times */ ++static INLINE uint16 ++bcmswap16(uint16 val) ++{ ++ return BCMSWAP16(val); ++} ++ ++static INLINE uint32 ++bcmswap32(uint32 val) ++{ ++ return BCMSWAP32(val); ++} ++ ++static INLINE uint32 ++bcmswap32by16(uint32 val) ++{ ++ return BCMSWAP32BY16(val); ++} ++ ++/* Reverse pairs of bytes in a buffer (not for high-performance use) */ ++/* buf - start of buffer of shorts to swap */ ++/* len - byte length of buffer */ ++static INLINE void ++bcmswap16_buf(uint16 *buf, uint len) ++{ ++ len = len / 2; ++ ++ while (len--) { ++ *buf = bcmswap16(*buf); ++ buf++; ++ } ++} ++ ++/* ++ * Store 16-bit value to unaligned little-endian byte array. ++ */ ++static INLINE void ++htol16_ua_store(uint16 val, uint8 *bytes) ++{ ++ bytes[0] = val & 0xff; ++ bytes[1] = val >> 8; ++} ++ ++/* ++ * Store 32-bit value to unaligned little-endian byte array. ++ */ ++static INLINE void ++htol32_ua_store(uint32 val, uint8 *bytes) ++{ ++ bytes[0] = val & 0xff; ++ bytes[1] = (val >> 8) & 0xff; ++ bytes[2] = (val >> 16) & 0xff; ++ bytes[3] = val >> 24; ++} ++ ++/* ++ * Store 16-bit value to unaligned network-(big-)endian byte array. ++ */ ++static INLINE void ++hton16_ua_store(uint16 val, uint8 *bytes) ++{ ++ bytes[0] = val >> 8; ++ bytes[1] = val & 0xff; ++} ++ ++/* ++ * Store 32-bit value to unaligned network-(big-)endian byte array. ++ */ ++static INLINE void ++hton32_ua_store(uint32 val, uint8 *bytes) ++{ ++ bytes[0] = val >> 24; ++ bytes[1] = (val >> 16) & 0xff; ++ bytes[2] = (val >> 8) & 0xff; ++ bytes[3] = val & 0xff; ++} ++ ++/* ++ * Load 16-bit value from unaligned little-endian byte array. ++ */ ++static INLINE uint16 ++ltoh16_ua(const void *bytes) ++{ ++ return _LTOH16_UA((const uint8 *)bytes); ++} ++ ++/* ++ * Load 32-bit value from unaligned little-endian byte array. ++ */ ++static INLINE uint32 ++ltoh32_ua(const void *bytes) ++{ ++ return _LTOH32_UA((const uint8 *)bytes); ++} ++ ++/* ++ * Load 16-bit value from unaligned big-(network-)endian byte array. ++ */ ++static INLINE uint16 ++ntoh16_ua(const void *bytes) ++{ ++ return _NTOH16_UA((const uint8 *)bytes); ++} ++ ++/* ++ * Load 32-bit value from unaligned big-(network-)endian byte array. ++ */ ++static INLINE uint32 ++ntoh32_ua(const void *bytes) ++{ ++ return _NTOH32_UA((const uint8 *)bytes); ++} ++ ++#endif /* !__GNUC__ */ ++#endif /* !_BCMENDIAN_H_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmenetmib.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmenetmib.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmenetmib.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmenetmib.h 2017-11-09 17:53:43.922294000 +0800 +@@ -0,0 +1,88 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Hardware-specific MIB definition for ++ * Broadcom Home Networking Division ++ * BCM44XX and BCM47XX 10/100 Mbps Ethernet cores. ++ * ++ * $Id: bcmenetmib.h 241182 2011-02-17 21:50:03Z $ ++ */ ++ ++#ifndef _bcmenetmib_h_ ++#define _bcmenetmib_h_ ++ ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif /* PAD */ ++ ++/* ++ * EMAC MIB Registers ++ */ ++typedef volatile struct { ++ uint32 tx_good_octets; ++ uint32 tx_good_pkts; ++ uint32 tx_octets; ++ uint32 tx_pkts; ++ uint32 tx_broadcast_pkts; ++ uint32 tx_multicast_pkts; ++ uint32 tx_len_64; ++ uint32 tx_len_65_to_127; ++ uint32 tx_len_128_to_255; ++ uint32 tx_len_256_to_511; ++ uint32 tx_len_512_to_1023; ++ uint32 tx_len_1024_to_max; ++ uint32 tx_jabber_pkts; ++ uint32 tx_oversize_pkts; ++ uint32 tx_fragment_pkts; ++ uint32 tx_underruns; ++ uint32 tx_total_cols; ++ uint32 tx_single_cols; ++ uint32 tx_multiple_cols; ++ uint32 tx_excessive_cols; ++ uint32 tx_late_cols; ++ uint32 tx_defered; ++ uint32 tx_carrier_lost; ++ uint32 tx_pause_pkts; ++ uint32 PAD[8]; ++ ++ uint32 rx_good_octets; ++ uint32 rx_good_pkts; ++ uint32 rx_octets; ++ uint32 rx_pkts; ++ uint32 rx_broadcast_pkts; ++ uint32 rx_multicast_pkts; ++ uint32 rx_len_64; ++ uint32 rx_len_65_to_127; ++ uint32 rx_len_128_to_255; ++ uint32 rx_len_256_to_511; ++ uint32 rx_len_512_to_1023; ++ uint32 rx_len_1024_to_max; ++ uint32 rx_jabber_pkts; ++ uint32 rx_oversize_pkts; ++ uint32 rx_fragment_pkts; ++ uint32 rx_missed_pkts; ++ uint32 rx_crc_align_errs; ++ uint32 rx_undersize; ++ uint32 rx_crc_errs; ++ uint32 rx_align_errs; ++ uint32 rx_symbol_errs; ++ uint32 rx_pause_pkts; ++ uint32 rx_nonpause_pkts; ++} bcmenetmib_t; ++ ++#endif /* _bcmenetmib_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmenetphy.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmenetphy.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmenetphy.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmenetphy.h 2017-11-09 17:53:43.923292000 +0800 +@@ -0,0 +1,86 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Misc Broadcom BCM47XX MDC/MDIO enet phy definitions. ++ * ++ * $Id: bcmenetphy.h 241182 2011-02-17 21:50:03Z $ ++ */ ++ ++#ifndef _bcmenetphy_h_ ++#define _bcmenetphy_h_ ++ ++/* phy address */ ++#define MAXEPHY 32 /* mdio phy addresses are 5bit quantities */ ++#define EPHY_MASK 0x1f /* phy mask */ ++#define EPHY_NONE 31 /* nvram: no phy present at all */ ++#define EPHY_NOREG 30 /* nvram: no local phy regs */ ++ ++#define MAXPHYREG 32 /* max 32 registers per phy */ ++ ++/* just a few phy registers */ ++#define CTL_RESET (1 << 15) /* reset */ ++#define CTL_LOOP (1 << 14) /* loopback */ ++#define CTL_SPEED (1 << 13) /* speed selection lsb 0=10, 1=100 */ ++#define CTL_ANENAB (1 << 12) /* autonegotiation enable */ ++#define CTL_RESTART (1 << 9) /* restart autonegotiation */ ++#define CTL_DUPLEX (1 << 8) /* duplex mode 0=half, 1=full */ ++#define CTL_SPEED_MSB (1 << 6) /* speed selection msb */ ++ ++#define CTL_SPEED_10 ((0 << 6) | (0 << 13)) /* speed selection CTL.6=0, CTL.13=0 */ ++#define CTL_SPEED_100 ((0 << 6) | (1 << 13)) /* speed selection CTL.6=0, CTL.13=1 */ ++#define CTL_SPEED_1000 ((1 << 6) | (0 << 13)) /* speed selection CTL.6=1, CTL.13=0 */ ++ ++#define ADV_10FULL (1 << 6) /* autonegotiate advertise 10full */ ++#define ADV_10HALF (1 << 5) /* autonegotiate advertise 10half */ ++#define ADV_100FULL (1 << 8) /* autonegotiate advertise 100full */ ++#define ADV_100HALF (1 << 7) /* autonegotiate advertise 100half */ ++#define ADV_PAUSE (1 << 10) /* autonegotiate advertise pause */ ++ ++/* link partner ability register */ ++#define LPA_SLCT 0x001f /* same as advertise selector */ ++#define LPA_10HALF 0x0020 /* can do 10mbps half-duplex */ ++#define LPA_10FULL 0x0040 /* can do 10mbps full-duplex */ ++#define LPA_100HALF 0x0080 /* can do 100mbps half-duplex */ ++#define LPA_100FULL 0x0100 /* can do 100mbps full-duplex */ ++#define LPA_100BASE4 0x0200 /* can do 100mbps 4k packets */ ++#define LPA_RFAULT 0x2000 /* link partner faulted */ ++#define LPA_LPACK 0x4000 /* link partner acked us */ ++#define LPA_NPAGE 0x8000 /* next page bit */ ++ ++#define LPA_DUPLEX (LPA_10FULL | LPA_100FULL) ++#define LPA_100 (LPA_100FULL | LPA_100HALF | LPA_100BASE4) ++ ++/* 1000BASE-T control register */ ++#define ADV_1000HALF 0x0100 /* advertise 1000BASE-T half duplex */ ++#define ADV_1000FULL 0x0200 /* advertise 1000BASE-T full duplex */ ++ ++/* 1000BASE-T status register */ ++#define LPA_1000HALF 0x0400 /* link partner 1000BASE-T half duplex */ ++#define LPA_1000FULL 0x0800 /* link partner 1000BASE-T full duplex */ ++ ++/* 1000BASE-T extended status register */ ++#define EST_1000THALF 0x1000 /* 1000BASE-T half duplex capable */ ++#define EST_1000TFULL 0x2000 /* 1000BASE-T full duplex capable */ ++#define EST_1000XHALF 0x4000 /* 1000BASE-X half duplex capable */ ++#define EST_1000XFULL 0x8000 /* 1000BASE-X full duplex capable */ ++ ++#define STAT_REMFAULT (1 << 4) /* remote fault */ ++#define STAT_LINK (1 << 2) /* link status */ ++#define STAT_JAB (1 << 1) /* jabber detected */ ++#define AUX_FORCED (1 << 2) /* forced 10/100 */ ++#define AUX_SPEED (1 << 1) /* speed 0=10mbps 1=100mbps */ ++#define AUX_DUPLEX (1 << 0) /* duplex 0=half 1=full */ ++ ++#endif /* _bcmenetphy_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmenetrxh.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmenetrxh.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmenetrxh.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmenetrxh.h 2017-11-09 17:53:43.927297000 +0800 +@@ -0,0 +1,50 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Hardware-specific Receive Data Header for the ++ * Broadcom Home Networking Division ++ * BCM44XX and BCM47XX 10/100 Mbps Ethernet cores. ++ * ++ * $Id: bcmenetrxh.h 241182 2011-02-17 21:50:03Z $ ++ */ ++ ++#ifndef _bcmenetrxh_h_ ++#define _bcmenetrxh_h_ ++ ++/* ++ * The Ethernet MAC core returns an 8-byte Receive Frame Data Header ++ * with every frame consisting of ++ * 16bits of frame length, followed by ++ * 16bits of EMAC rx descriptor info, followed by 32bits of undefined. ++ */ ++typedef volatile struct { ++ uint16 len; ++ uint16 flags; ++ uint16 pad[12]; ++} bcmenetrxh_t; ++ ++#define RXHDR_LEN 28 /* Header length */ ++ ++#define RXF_L ((uint16)1 << 11) /* last buffer in a frame */ ++#define RXF_MISS ((uint16)1 << 7) /* received due to promisc mode */ ++#define RXF_BRDCAST ((uint16)1 << 6) /* dest is broadcast address */ ++#define RXF_MULT ((uint16)1 << 5) /* dest is multicast address */ ++#define RXF_LG ((uint16)1 << 4) /* frame length > rxmaxlength */ ++#define RXF_NO ((uint16)1 << 3) /* odd number of nibbles */ ++#define RXF_RXER ((uint16)1 << 2) /* receive symbol error */ ++#define RXF_CRC ((uint16)1 << 1) /* crc error */ ++#define RXF_OV ((uint16)1 << 0) /* fifo overflow */ ++ ++#endif /* _bcmenetrxh_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmgmacmib.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmgmacmib.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmgmacmib.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmgmacmib.h 2017-11-09 17:53:43.928296000 +0800 +@@ -0,0 +1,117 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Hardware-specific MIB definition for ++ * Broadcom Home Networking Division ++ * GbE Unimac core ++ * ++ * $Id: bcmgmacmib.h 241182 2011-02-17 21:50:03Z $ ++ */ ++ ++#ifndef _bcmgmacmib_h_ ++#define _bcmgmacmib_h_ ++ ++ ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif /* PAD */ ++ ++/* GMAC MIB structure */ ++ ++typedef struct _gmacmib { ++ uint32 tx_good_octets; /* 0x300 */ ++ uint32 tx_good_octets_high; /* 0x304 */ ++ uint32 tx_good_pkts; /* 0x308 */ ++ uint32 tx_octets; /* 0x30c */ ++ uint32 tx_octets_high; /* 0x310 */ ++ uint32 tx_pkts; /* 0x314 */ ++ uint32 tx_broadcast_pkts; /* 0x318 */ ++ uint32 tx_multicast_pkts; /* 0x31c */ ++ uint32 tx_len_64; /* 0x320 */ ++ uint32 tx_len_65_to_127; /* 0x324 */ ++ uint32 tx_len_128_to_255; /* 0x328 */ ++ uint32 tx_len_256_to_511; /* 0x32c */ ++ uint32 tx_len_512_to_1023; /* 0x330 */ ++ uint32 tx_len_1024_to_1522; /* 0x334 */ ++ uint32 tx_len_1523_to_2047; /* 0x338 */ ++ uint32 tx_len_2048_to_4095; /* 0x33c */ ++ uint32 tx_len_4095_to_8191; /* 0x340 */ ++ uint32 tx_len_8192_to_max; /* 0x344 */ ++ uint32 tx_jabber_pkts; /* 0x348 */ ++ uint32 tx_oversize_pkts; /* 0x34c */ ++ uint32 tx_fragment_pkts; /* 0x350 */ ++ uint32 tx_underruns; /* 0x354 */ ++ uint32 tx_total_cols; /* 0x358 */ ++ uint32 tx_single_cols; /* 0x35c */ ++ uint32 tx_multiple_cols; /* 0x360 */ ++ uint32 tx_excessive_cols; /* 0x364 */ ++ uint32 tx_late_cols; /* 0x368 */ ++ uint32 tx_defered; /* 0x36c */ ++ uint32 tx_carrier_lost; /* 0x370 */ ++ uint32 tx_pause_pkts; /* 0x374 */ ++ uint32 tx_uni_pkts; /* 0x378 */ ++ uint32 tx_q0_pkts; /* 0x37c */ ++ uint32 tx_q0_octets; /* 0x380 */ ++ uint32 tx_q0_octets_high; /* 0x384 */ ++ uint32 tx_q1_pkts; /* 0x388 */ ++ uint32 tx_q1_octets; /* 0x38c */ ++ uint32 tx_q1_octets_high; /* 0x390 */ ++ uint32 tx_q2_pkts; /* 0x394 */ ++ uint32 tx_q2_octets; /* 0x398 */ ++ uint32 tx_q2_octets_high; /* 0x39c */ ++ uint32 tx_q3_pkts; /* 0x3a0 */ ++ uint32 tx_q3_octets; /* 0x3a4 */ ++ uint32 tx_q3_octets_high; /* 0x3a8 */ ++ uint32 PAD; ++ uint32 rx_good_octets; /* 0x3b0 */ ++ uint32 rx_good_octets_high; /* 0x3b4 */ ++ uint32 rx_good_pkts; /* 0x3b8 */ ++ uint32 rx_octets; /* 0x3bc */ ++ uint32 rx_octets_high; /* 0x3c0 */ ++ uint32 rx_pkts; /* 0x3c4 */ ++ uint32 rx_broadcast_pkts; /* 0x3c8 */ ++ uint32 rx_multicast_pkts; /* 0x3cc */ ++ uint32 rx_len_64; /* 0x3d0 */ ++ uint32 rx_len_65_to_127; /* 0x3d4 */ ++ uint32 rx_len_128_to_255; /* 0x3d8 */ ++ uint32 rx_len_256_to_511; /* 0x3dc */ ++ uint32 rx_len_512_to_1023; /* 0x3e0 */ ++ uint32 rx_len_1024_to_1522; /* 0x3e4 */ ++ uint32 rx_len_1523_to_2047; /* 0x3e8 */ ++ uint32 rx_len_2048_to_4095; /* 0x3ec */ ++ uint32 rx_len_4095_to_8191; /* 0x3f0 */ ++ uint32 rx_len_8192_to_max; /* 0x3f4 */ ++ uint32 rx_jabber_pkts; /* 0x3f8 */ ++ uint32 rx_oversize_pkts; /* 0x3fc */ ++ uint32 rx_fragment_pkts; /* 0x400 */ ++ uint32 rx_missed_pkts; /* 0x404 */ ++ uint32 rx_crc_align_errs; /* 0x408 */ ++ uint32 rx_undersize; /* 0x40c */ ++ uint32 rx_crc_errs; /* 0x410 */ ++ uint32 rx_align_errs; /* 0x414 */ ++ uint32 rx_symbol_errs; /* 0x418 */ ++ uint32 rx_pause_pkts; /* 0x41c */ ++ uint32 rx_nonpause_pkts; /* 0x420 */ ++ uint32 rx_sachanges; /* 0x424 */ ++ uint32 rx_uni_pkts; /* 0x428 */ ++} gmacmib_t; ++ ++#define GM_MIB_BASE 0x300 ++#define GM_MIB_LIMIT 0x800 ++ ++#endif /* _bcmgmacmib_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmgmacrxh.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmgmacrxh.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmgmacrxh.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmgmacrxh.h 2017-11-09 17:53:43.929307000 +0800 +@@ -0,0 +1,53 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Hardware-specific Receive Data Header for the ++ * Broadcom Home Networking Division ++ * BCM47XX GbE cores. ++ * ++ * $Id: bcmgmacrxh.h 241182 2011-02-17 21:50:03Z $ ++ */ ++ ++#ifndef _bcmgmacrxh_h_ ++#define _bcmgmacrxh_h_ ++ ++/* ++ * The Ethernet GMAC core returns an 8-byte Receive Frame Data Header ++ * with every frame consisting of ++ * 16 bits of frame length, followed by ++ * 16 bits of GMAC rx descriptor info, followed by 32bits of undefined. ++ */ ++typedef volatile struct { ++ uint16 len; ++ uint16 flags; ++ uint16 pad[12]; ++} bcmgmacrxh_t; ++ ++#define RXHDR_LEN 28 /* Header length */ ++ ++#define GRXF_DT_MASK ((uint16)0xf) /* data type */ ++#define GRXF_DT_SHIFT 12 ++#define GRXF_DC_MASK ((uint16)0xf) /* (num descr to xfer the frame) - 1 */ ++#define GRXF_DC_SHIFT 8 ++#define GRXF_OVF ((uint16)1 << 7) /* overflow error occured */ ++#define GRXF_CTFERR ((uint16)1 << 6) /* overflow error occured */ ++#define GRXF_OVERSIZE ((uint16)1 << 4) /* frame size > rxmaxlength */ ++#define GRXF_CRC ((uint16)1 << 3) /* crc error */ ++#define GRXF_VLAN ((uint16)1 << 2) /* vlan tag detected */ ++#define GRXF_PT_MASK ((uint16)3) /* packet type 0 - Unicast, ++ * 1 - Multicast, 2 - Broadcast ++ */ ++ ++#endif /* _bcmgmacrxh_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_egphy28.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_egphy28.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_egphy28.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_egphy28.h 2017-11-09 17:53:43.930299000 +0800 +@@ -0,0 +1,68 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * These routines provide access to the external phy ++ * ++ */ ++ ++#ifndef _EGPHY28_H_ ++#define _EGPHY28_H_ ++ ++#define EGPHY28_REG_RDB_ADDR 0x1e ++#define EGPHY28_REG_RDB_DATA 0x1f ++ ++#define EGPHY28_RDB_ACCESS_ADDR_1 0x17 ++#define EGPHY28_RDB_ACCESS_DATA_1 0x0f7e ++#define EGPHY28_RDB_ACCESS_ADDR_2 0x15 ++#define EGPHY28_RDB_ACCESS_DATA_2 0x0000 ++ ++/* Generic MII registers */ ++#define EGPHY28_COPPER_MII_CTRL 0x00 ++#define EGPHY28_PHY_ID_MSB 0x02 /* PHY ID MSB */ ++#define EGPHY28_PHY_ID_LSB 0x03 /* PHY ID LSB */ ++#define EGPHY28_MII_ADVERTISE 0x04 /* Advertisement control reg */ ++#define EGPHY28_MII_CTRL1000 0x09 /* 1000BASE-T control */ ++#define EGPGY28_MII_ECONTROL 0x10 /* Extended Control */ ++#define EGPHY28_COPPER_MISC_CTRL 0x2f /* COPPER MISC CONTROL */ ++ ++/* For EGPHY28_COPPER_MII_CTRL(0x00) */ ++#define BMCR_FULLDPLX 0x0100 /* Full duplex */ ++#define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */ ++#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */ ++#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */ ++#define BMCR_PDOWN 0x0800 /* Powerdown EGPHY28 */ ++#define BMCR_RESET 0x8000 /* Reset EGPHY28 */ ++ ++/* For EGPHY28_MII_ADVERTISE(0x04) */ ++#define ADVERTISE_1000HALF 0x0100 /* Advertise 1000BASE-T half duplex */ ++#define ADVERTISE_CSMA 0x0001 /* Only selector supported */ ++#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */ ++#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */ ++#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */ ++#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */ ++ ++/* For EGPHY28_MII_CTRL1000(0x09) */ ++#define ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */ ++#define REPEATER_DTE 0x0400 /* Repeater/switch or DTE port type */ ++ ++/* For EGPHY28_COPPER_MISC_CTRL(0x2f) */ ++#define BMCR_FORCE_AUTO_MDIX 0x0200 ++ ++extern int egphy28_enable_set(u32 phy_addr, int enable); ++extern int egphy28_init(void __iomem *base, u32 phy_addr); ++extern int egphy28_enable_set(u32 phy_addr, int enable); ++extern int egphy28_force_auto_mdix(u32 phy_addr, int enable); ++ ++#endif +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_phy.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_phy.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_phy.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_phy.h 2017-11-09 17:53:43.931300000 +0800 +@@ -0,0 +1,290 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * These routines provide access to the external phy ++ * ++ */ ++ ++#ifndef _bcm_iproc_phy_h_ ++#define _bcm_iproc_phy_h_ ++ ++ ++#define PHY_ADDR_MASK 0x00001F ++#define PHY_BUS_MASK 0x000020 ++#define PHY_BANK_MASK 0x001F00 ++#define PHY_FLAG_MASK 0xFF0000 ++#define PHY_ADDR(_flag, _bank, _bus, _addr) \ ++ (((_flag << 16) & PHY_FLAG_MASK) | ((_bank << 8) & PHY_BANK_MASK) | \ ++ ((_bus << 5) & PHY_BUS_MASK) | ((_addr << 0) & PHY_ADDR_MASK)) ++ ++#define PHY_REG_ADDR(_addr) ((_addr & PHY_ADDR_MASK) >> 0) ++#define PHY_REG_BUS(_addr) ((_addr & PHY_BUS_MASK) >> 5) ++#define PHY_REG_BANK(_addr) ((_addr & PHY_BANK_MASK) >> 8) ++#define PHY_REG_FLAGS(_addr) ((_addr & PHY_FLAG_MASK) >> 16) ++ ++/* Flags for phy register */ ++#define PHY_REG_FLAGS_NONE (0) ++#define PHY_REG_FLAGS_1000X (1 << 0) ++#define PHY_REG_FLAGS_PRI_SERDES (1 << 1) ++#define PHY_REG_FLAGS_RDB (1 << 2) ++#define PHY_REG_FLAGS_QSGMII (1 << 3) ++#define PHY_REG_FLAGS_FIBER (PHY_REG_FLAGS_1000X | \ ++ PHY_REG_FLAGS_PRI_SERDES) ++ ++typedef enum { ++ SOC_E_NONE = 0, ++ SOC_E_INTERNAL = -1, ++ SOC_E_MEMORY = -2, ++ SOC_E_UNIT = -3, ++ SOC_E_PARAM = -4, ++ SOC_E_EMPTY = -5, ++ SOC_E_FULL = -6, ++ SOC_E_NOT_FOUND = -7, ++ SOC_E_EXISTS = -8, ++ SOC_E_TIMEOUT = -9, ++ SOC_E_BUSY = -10, ++ SOC_E_FAIL = -11, ++ SOC_E_DISABLED = -12, ++ SOC_E_BADID = -13, ++ SOC_E_RESOURCE = -14, ++ SOC_E_CONFIG = -15, ++ SOC_E_UNAVAIL = -16, ++ SOC_E_INIT = -17, ++ SOC_E_PORT = -18, ++ ++ SOC_E_LIMIT = -19 /* Must come last */ ++} soc_error_t; ++ ++#define SOC_SUCCESS(rv) ((rv) >= 0) ++#define SOC_FAILURE(rv) ((rv) < 0) ++ ++typedef enum _soc_port_if_e { ++ SOC_PORT_IF_NOCXN, /* No physical connection */ ++ SOC_PORT_IF_NULL, /* Pass-through connection without PHY */ ++ SOC_PORT_IF_MII, ++ SOC_PORT_IF_GMII, ++ SOC_PORT_IF_SGMII, ++ SOC_PORT_IF_TBI, ++ SOC_PORT_IF_XGMII, ++ SOC_PORT_IF_RGMII, ++ SOC_PORT_IF_RvMII, ++ SOC_PORT_IF_SFI, ++ SOC_PORT_IF_XFI, ++ SOC_PORT_IF_KR, ++ SOC_PORT_IF_KR4, ++ SOC_PORT_IF_CR, ++ SOC_PORT_IF_CR4, ++ SOC_PORT_IF_XLAUI, ++ SOC_PORT_IF_SR, ++ SOC_PORT_IF_RXAUI, ++ SOC_PORT_IF_XAUI, ++ SOC_PORT_IF_SPAUI, ++ SOC_PORT_IF_QSGMII, ++ SOC_PORT_IF_ILKN, ++ SOC_PORT_IF_RCY, ++ SOC_PORT_IF_FAT_PIPE, ++ SOC_PORT_IF_CGMII, ++ SOC_PORT_IF_CAUI, ++ SOC_PORT_IF_LR, ++ SOC_PORT_IF_LR4, ++ SOC_PORT_IF_SR4, ++ SOC_PORT_IF_KX, ++ SOC_PORT_IF_CPU, ++ SOC_PORT_IF_OLP, ++ SOC_PORT_IF_OAMP, ++ SOC_PORT_IF_ERP, ++ SOC_PORT_IF_COUNT /* last, please */ ++} _soc_port_if_t; ++typedef _soc_port_if_t soc_port_if_t; ++ ++ ++/* 1000BASE-T/100BASE-TX/10BASE-T MII Control Register (Addr 00h) */ ++#define PHY_MII_CTRLr_FLAGS 0x00 ++#define PHY_MII_CTRLr_BANK 0x0000 ++#define PHY_MII_CTRLr_ADDR 0x00 ++/* 1000BASE-T/100BASE-TX/10BASE-T MII Status Register (ADDR 01h) */ ++#define PHY_MII_STATr_FLAGS 0x00 ++#define PHY_MII_STATr_BANK 0x0000 ++#define PHY_MII_STATr_ADDR 0x01 ++/* 1000BASE-T/100BASE-TX/10BASE-T PHY Identifier Register (ADDR 02h) */ ++#define PHY_MII_PHY_ID0r_FLAGS _SOC_PHY_REG_DIRECT ++#define PHY_MII_PHY_ID0r_BANK 0x0000 ++#define PHY_MII_PHY_ID0r_ADDR 0x02 ++/* 1000BASE-T/100BASE-TX/10BASE-T PHY Identifier Register (ADDR 03h) */ ++#define PHY_MII_PHY_ID1r_FLAGS _SOC_PHY_REG_DIRECT ++#define PHY_MII_PHY_ID1r_BANK 0x0000 ++#define PHY_MII_PHY_ID1r_ADDR 0x03 ++/* 1000BASE-T/100BASE-TX/10BASE-T Auto-neg Advertisment Register (ADDR 04h) */ ++#define PHY_MII_ANAr_FLAGS 0x00 ++#define PHY_MII_ANAr_BANK 0x0000 ++#define PHY_MII_ANAr_ADDR 0x04 ++/* 1000BASE-T/100BASE-TX/10BASE-T Auto-neg Link Partner Ability (ADDR 05h) */ ++#define PHY_MII_ANPr_FLAGS 0x00 ++#define PHY_MII_ANPr_BANK 0x0000 ++#define PHY_MII_ANPr_ADDR 0x05 ++/* 1000BASE-T Control Register (ADDR 09h) */ ++#define PHY_MII_GB_CTRLr_FLAGS 0x00 ++#define PHY_MII_GB_CTRLr_BANK 0x0000 ++#define PHY_MII_GB_CTRLr_ADDR 0x09 ++/* 1000BASE-T Status Register (ADDR 0ah) */ ++#define PHY_MII_GB_STATr_FLAGS 0x00 ++#define PHY_MII_GB_STATr_BANK 0x0000 ++#define PHY_MII_GB_STATr_ADDR 0x0a ++/* 1000BASE-T/100BASE-TX/10BASE-T IEEE Extended Status Register (ADDR 0fh) */ ++#define PHY_MII_ESRr_FLAGS 0x00 ++#define PHY_MII_ESRr_BANK 0x0000 ++#define PHY_MII_ESRr_ADDR 0x0f ++/* 1000BASE-T/100BASE-TX/10BASE-T PHY Extended Control Register (ADDR 10h) */ ++#define PHY_MII_ECRr_FLAGS 0x00 ++#define PHY_MII_ECRr_BANK 0x0000 ++#define PHY_MII_ECRr_ADDR 0x10 ++/* 1000BASE-T/100BASE-TX/10BASE-T Auxiliary Control Reg (ADDR 18h Shadow 000)*/ ++#define PHY_MII_AUX_CTRLr_FLAGS 0x00 ++#define PHY_MII_AUX_CTRLr_BANK 0x0000 ++#define PHY_MII_AUX_CTRLr_ADDR 0x18 ++/* 1000BASE-T/100BASE-TX/10BASE-T Power/MII Control Reg (ADDR 18h Shadow 010)*/ ++#define PHY_MII_POWER_CTRLr_FLAGS 0x00 ++#define PHY_MII_POWER_CTRLr_BANK 0x0002 ++#define PHY_MII_POWER_CTRLr_ADDR 0x18 ++/* 1000BASE-T/100BASE-TX/10BASE-T Misc Control Reg (ADDR 18h Shadow 111)*/ ++#define PHY_MII_MISC_CTRLr_FLAGS 0x00 ++#define PHY_MII_MISC_CTRLr_BANK 0x0007 ++#define PHY_MII_MISC_CTRLr_ADDR 0x18 ++/* Auxiliary 1000BASE-X Control Reg (ADDR 1ch shadow 11011) */ ++#define PHY_AUX_1000X_CTRLr_FLAGS 0x00 ++#define PHY_AUX_1000X_CTRLr_BANK 0x001B ++#define PHY_AUX_1000X_CTRLr_ADDRS 0x1c ++/* Mode Control Reg (ADDR 1ch shadow 11111) */ ++#define PHY_MODE_CTRLr_FLAGS 0x00 ++#define PHY_MODE_CTRLr_BANK 0x001F ++#define PHY_MODE_CTRLr_ADDR 0x1c ++ ++/* ++ * Primary SerDes Registers ++ */ ++/* 1000BASE-X MII Control Register (Addr 00h) */ ++#define PHY_1000X_MII_CTRLr_FLAGS SOC_PHY_REG_1000X ++#define PHY_1000X_MII_CTRLr_BANK 0x0000 ++#define PHY_1000X_MII_CTRLr_ADDR 0x00 ++ ++ ++/* MII Control Register: bit definitions */ ++#define MII_CTRL_FS_2500 (1 << 5) /* Force speed to 2500 Mbps */ ++#define MII_CTRL_SS_MSB (1 << 6) /* Speed select, MSb */ ++#define MII_CTRL_CST (1 << 7) /* Collision Signal test */ ++#define MII_CTRL_FD (1 << 8) /* Full Duplex */ ++#define MII_CTRL_RAN (1 << 9) /* Restart Autonegotiation */ ++#define MII_CTRL_IP (1 << 10) /* Isolate Phy */ ++#define MII_CTRL_PD (1 << 11) /* Power Down */ ++#define MII_CTRL_AE (1 << 12) /* Autonegotiation enable */ ++#define MII_CTRL_SS_LSB (1 << 13) /* Speed select, LSb */ ++#define MII_CTRL_LE (1 << 14) /* Loopback enable */ ++#define MII_CTRL_RESET (1 << 15) /* PHY reset */ ++ ++#define MII_CTRL_SS(_x) ((_x) & (MII_CTRL_SS_LSB|MII_CTRL_SS_MSB)) ++#define MII_CTRL_SS_10 0 ++#define MII_CTRL_SS_100 (MII_CTRL_SS_LSB) ++#define MII_CTRL_SS_1000 (MII_CTRL_SS_MSB) ++#define MII_CTRL_SS_INVALID (MII_CTRL_SS_LSB | MII_CTRL_SS_MSB) ++#define MII_CTRL_SS_MASK (MII_CTRL_SS_LSB | MII_CTRL_SS_MSB) ++ ++/* ++ * MII Status Register: See 802.3, 1998 pg 544 ++ */ ++#define MII_STAT_EXT (1 << 0) /* Extended Registers */ ++#define MII_STAT_JBBR (1 << 1) /* Jabber Detected */ ++#define MII_STAT_LA (1 << 2) /* Link Active */ ++#define MII_STAT_AN_CAP (1 << 3) /* Autoneg capable */ ++#define MII_STAT_RF (1 << 4) /* Remote Fault */ ++#define MII_STAT_AN_DONE (1 << 5) /* Autoneg complete */ ++#define MII_STAT_MF_PS (1 << 6) /* Preamble suppression */ ++#define MII_STAT_ES (1 << 8) /* Extended status (R15) */ ++#define MII_STAT_HD_100_T2 (1 << 9) /* Half duplex 100Mb/s supported */ ++#define MII_STAT_FD_100_T2 (1 << 10)/* Full duplex 100Mb/s supported */ ++#define MII_STAT_HD_10 (1 << 11)/* Half duplex 100Mb/s supported */ ++#define MII_STAT_FD_10 (1 << 12)/* Full duplex 100Mb/s supported */ ++#define MII_STAT_HD_100 (1 << 13)/* Half duplex 100Mb/s supported */ ++#define MII_STAT_FD_100 (1 << 14)/* Full duplex 100Mb/s supported */ ++#define MII_STAT_100_T4 (1 << 15)/* Full duplex 100Mb/s supported */ ++ ++/* ++ * MII Link Advertisment ++ */ ++#define MII_ANA_ASF (1 << 0)/* Advertise Selector Field */ ++#define MII_ANA_HD_10 (1 << 5)/* Half duplex 10Mb/s supported */ ++#define MII_ANA_FD_1000X (1 << 5)/* Full duplex for 1000BASE-X */ ++#define MII_ANA_FD_10 (1 << 6)/* Full duplex 10Mb/s supported */ ++#define MII_ANA_HD_1000X (1 << 6)/* Half duplex for 1000BASE-X */ ++#define MII_ANA_HD_100 (1 << 7)/* Half duplex 100Mb/s supported */ ++#define MII_ANA_1000X_PAUSE (1 << 7)/* Pause supported for 1000BASE-X */ ++#define MII_ANA_FD_100 (1 << 8)/* Full duplex 100Mb/s supported */ ++#define MII_ANA_1000X_ASYM_PAUSE (1 << 8)/* Asymmetric pause supported for 1000BASE-X */ ++#define MII_ANA_T4 (1 << 9)/* T4 */ ++#define MII_ANA_PAUSE (1 << 10)/* Pause supported */ ++#define MII_ANA_ASYM_PAUSE (1 << 11)/* Asymmetric pause supported */ ++#define MII_ANA_RF (1 << 13)/* Remote fault */ ++#define MII_ANA_NP (1 << 15)/* Next Page */ ++ ++#define MII_ANA_ASF_802_3 (1) /* 802.3 PHY */ ++ ++/* ++ * 1000Base-T Control Register ++ */ ++#define MII_GB_CTRL_MS_MAN (1 << 12) /* Manual Master/Slave mode */ ++#define MII_GB_CTRL_MS (1 << 11) /* Master/Slave negotiation mode */ ++#define MII_GB_CTRL_PT (1 << 10) /* Port type */ ++#define MII_GB_CTRL_ADV_1000FD (1 << 9) /* Advertise 1000Base-T FD */ ++#define MII_GB_CTRL_ADV_1000HD (1 << 8) /* Advertise 1000Base-T HD */ ++ ++/* ++ * 1000Base-T Status Register ++ */ ++#define MII_GB_STAT_MS_FAULT (1 << 15) /* Master/Slave Fault */ ++#define MII_GB_STAT_MS (1 << 14) /* Master/Slave, 1 == Master */ ++#define MII_GB_STAT_LRS (1 << 13) /* Local receiver status */ ++#define MII_GB_STAT_RRS (1 << 12) /* Remote receiver status */ ++#define MII_GB_STAT_LP_1000FD (1 << 11) /* Link partner 1000FD capable */ ++#define MII_GB_STAT_LP_1000HD (1 << 10) /* Link partner 1000HD capable */ ++#define MII_GB_STAT_IDE (0xff << 0) /* Idle error count */ ++ ++/* ++ * IEEE Extended Status Register ++ */ ++#define MII_ESR_1000_X_FD (1 << 15) /* 1000Base-T FD capable */ ++#define MII_ESR_1000_X_HD (1 << 14) /* 1000Base-T HD capable */ ++#define MII_ESR_1000_T_FD (1 << 13) /* 1000Base-T FD capable */ ++#define MII_ESR_1000_T_HD (1 << 12) /* 1000Base-T FD capable */ ++ ++/* MII Extended Control Register (BROADCOM) */ ++#define MII_ECR_FE (1 << 0) /* FIFO Elasticity */ ++#define MII_ECR_TLLM (1 << 1) /* Three link LED mode */ ++#define MII_ECR_ET_IPG (1 << 2) /* Extended XMIT IPG mode */ ++#define MII_ECR_FLED_OFF (1 << 3) /* Force LED off */ ++#define MII_ECR_FLED_ON (1 << 4) /* Force LED on */ ++#define MII_ECR_ELT (1 << 5) /* Enable LED traffic */ ++#define MII_ECR_RS (1 << 6) /* Reset Scrambler */ ++#define MII_ECR_BRSA (1 << 7) /* Bypass Receive Sym. align */ ++#define MII_ECR_BMLT3 (1 << 8) /* Bypass MLT3 Encoder/Decoder */ ++#define MII_ECR_BSD (1 << 9) /* Bypass Scramble/Descramble */ ++#define MII_ECR_B4B5B (1 << 10) /* Bypass 4B/5B Encode/Decode */ ++#define MII_ECR_FI (1 << 11) /* Force Interrupt */ ++#define MII_ECR_ID (1 << 12) /* Interrupt Disable */ ++#define MII_ECR_TD (1 << 13) /* XMIT Disable */ ++#define MII_ECR_DAMC (1 << 14) /* DIsable Auto-MDI Crossover */ ++#define MII_ECR_10B (1 << 15) /* 1 == 10B, 0 == GMII */ ++ ++/* MISC Control Register (Addr 18h, Shadow Value 111) */ ++#define MII_FORCED_AUTO_MDIX (1 << 9) /* 1 == AUTO-MDIX enabled when AN disabled */ ++#endif /* _bcm_iproc_phy_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_phy5221.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_phy5221.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_phy5221.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_phy5221.h 2017-11-09 17:53:43.932294000 +0800 +@@ -0,0 +1,45 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * These routines provide access to the external phy ++ * ++ */ ++ ++#ifndef _bcm_iproc_phy5221_h_ ++#define _bcm_iproc_phy5221_h_ ++ ++ ++/* ---- Include Files ---------------------------------------------------- */ ++#include ++ ++#define PHY_AUX_MULTIPLE_PHYr_BANK 0x0000 ++#define PHY_AUX_MULTIPLE_PHYr_ADDR 0x1e ++ ++#define PHY522X_SUPER_ISOLATE_MODE (1<<3) ++ ++/* ---- External Function Prototypes ------------------------------------- */ ++ ++extern int phy5221_wr_reg(uint eth_num, uint phyaddr, uint16 reg_bank, ++ uint8 reg_addr, uint16 *data); ++extern int phy5221_rd_reg(uint eth_num, uint phyaddr, uint16 reg_bank, ++ uint8 reg_addr, uint16 *data); ++extern int phy5221_mod_reg(uint eth_num, uint phyaddr, uint16 reg_bank, ++ uint8 reg_addr, uint16 data, uint16 mask); ++extern int phy5221_init(uint eth_num, uint phyaddr); ++extern int phy5221_link_get(uint eth_num, uint phyaddr, int *link); ++extern int phy5221_enable_set(uint eth_num, uint phyaddr, int enable); ++extern int phy5221_speed_get(uint eth_num, uint phyaddr, int *speed, int *duplex); ++ ++#endif /* _bcm_iproc_phy5221_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_phy5461s.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_phy5461s.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_phy5461s.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_phy5461s.h 2017-11-09 17:53:43.933291000 +0800 +@@ -0,0 +1,46 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * These routines provide access to the external phy ++ * ++ */ ++ ++#ifndef _bcm_iproc_phy5461s_h_ ++#define _bcm_iproc_phy5461s_h_ ++ ++ ++/* ---- Include Files ---------------------------------------------------- */ ++#include ++ ++/* Indirect PHY register address flags */ ++#define SOC_PHY_REG_RESERVE_ACCESS 0x20000000 ++#define SOC_PHY_REG_1000X 0x40000000 ++#define SOC_PHY_REG_INDIRECT 0x80000000 ++#define _SOC_PHY_REG_DIRECT ((SOC_PHY_REG_1000X << 1) | (SOC_PHY_REG_1000X >> 1)) ++ ++/* ---- External Function Prototypes ------------------------------------- */ ++ ++extern int phy5461_wr_reg(uint eth_num, uint phyaddr, uint32 flags, uint16 reg_bank, ++ uint8 reg_addr, uint16 *data); ++extern int phy5461_rd_reg(uint eth_num, uint phyaddr, uint32 flags, uint16 reg_bank, ++ uint8 reg_addr, uint16 *data); ++extern int phy5461_mod_reg(uint eth_num, uint phyaddr, uint32 flags, uint16 reg_bank, ++ uint8 reg_addr, uint16 data, uint16 mask); ++extern int phy5461_init(uint eth_num, uint phyaddr); ++extern int phy5461_link_get(uint eth_num, uint phyaddr, int *link); ++extern int phy5461_enable_set(uint eth_num, uint phyaddr, int enable); ++extern int phy5461_speed_get(uint eth_num, uint phyaddr, int *speed, int *duplex); ++ ++#endif /* _bcm_iproc_phy5461s_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_phy5481.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_phy5481.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_phy5481.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_phy5481.h 2017-11-09 17:53:43.933313000 +0800 +@@ -0,0 +1,45 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * These routines provide access to the external phy ++ * ++ */ ++ ++#ifndef _bcm_iproc_phy5481_h_ ++#define _bcm_iproc_phy5481_h_ ++ ++ ++/* ---- Include Files ---------------------------------------------------- */ ++#include ++ ++// #define PHY_AUX_MULTIPLE_PHYr_BANK 0x0000 ++// #define PHY_AUX_MULTIPLE_PHYr_ADDR 0x1e ++ ++#define PHY5481_SUPER_ISOLATE_MODE (1U<<5) ++ ++/* ---- External Function Prototypes ------------------------------------- */ ++ ++extern int phy5481_wr_reg(uint eth_num, uint phyaddr, uint16 reg_bank, ++ uint8 reg_addr, uint16 *data); ++extern int phy5481_rd_reg(uint eth_num, uint phyaddr, uint16 reg_bank, ++ uint8 reg_addr, uint16 *data); ++extern int phy5481_mod_reg(uint eth_num, uint phyaddr, uint16 reg_bank, ++ uint8 reg_addr, uint16 data, uint16 mask); ++extern int phy5481_init(uint eth_num, uint phyaddr); ++extern int phy5481_link_get(uint eth_num, uint phyaddr, int *link); ++extern int phy5481_enable_set(uint eth_num, uint phyaddr, int enable); ++extern int phy5481_speed_get(uint eth_num, uint phyaddr, int *speed, int *duplex); ++ ++#endif /* _bcm_iproc_phy5481_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_serdes.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_serdes.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_serdes.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_serdes.h 2017-11-09 17:53:43.934297000 +0800 +@@ -0,0 +1,78 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * These routines provide access to the serdes ++ * ++ */ ++ ++#ifndef _bcm_iproc_serdes_h_ ++#define _bcm_iproc_serdes_h_ ++ ++ ++/* ---- Include Files ---------------------------------------------------- */ ++#include ++ ++#define PHY_REG_BLK_ADDR 0x001f /* GLOBAL BLOCK ADDRESS REGISTER */ ++ ++/* ++ * MII Link Advertisment (Clause 37) ++ */ ++#define MII_ANA_C37_NP (1 << 15) /* Next Page */ ++#define MII_ANA_C37_RF_OK (0 << 12) /* No error, link OK */ ++#define MII_ANA_C37_RF_LINK_FAIL (1 << 12) /* Offline */ ++#define MII_ANA_C37_RF_OFFLINE (2 << 12) /* Link failure */ ++#define MII_ANA_C37_RF_AN_ERR (3 << 12) /* Auto-Negotiation Error */ ++#define MII_ANA_C37_PAUSE (1 << 7) /* Symmetric Pause */ ++#define MII_ANA_C37_ASYM_PAUSE (1 << 8) /* Asymmetric Pause */ ++#define MII_ANA_C37_HD (1 << 6) /* Half duplex */ ++#define MII_ANA_C37_FD (1 << 5) /* Full duplex */ ++ ++/* MII Control Register: bit definitions */ ++ ++#define MII_CTRL_FS_2500 (1 << 5) /* Force speed to 2500 Mbps */ ++#define MII_CTRL_SS_MSB (1 << 6) /* Speed select, MSb */ ++#define MII_CTRL_CST (1 << 7) /* Collision Signal test */ ++#define MII_CTRL_FD (1 << 8) /* Full Duplex */ ++#define MII_CTRL_RAN (1 << 9) /* Restart Autonegotiation */ ++#define MII_CTRL_IP (1 << 10) /* Isolate Phy */ ++#define MII_CTRL_PD (1 << 11) /* Power Down */ ++#define MII_CTRL_AE (1 << 12) /* Autonegotiation enable */ ++#define MII_CTRL_SS_LSB (1 << 13) /* Speed select, LSb */ ++#define MII_CTRL_LE (1 << 14) /* Loopback enable */ ++#define MII_CTRL_RESET (1 << 15) /* PHY reset */ ++ ++#define MII_CTRL_SS(_x) ((_x) & (MII_CTRL_SS_LSB|MII_CTRL_SS_MSB)) ++#define MII_CTRL_SS_10 0 ++#define MII_CTRL_SS_100 (MII_CTRL_SS_LSB) ++#define MII_CTRL_SS_1000 (MII_CTRL_SS_MSB) ++#define MII_CTRL_SS_INVALID (MII_CTRL_SS_LSB | MII_CTRL_SS_MSB) ++#define MII_CTRL_SS_MASK (MII_CTRL_SS_LSB | MII_CTRL_SS_MSB) ++ ++/* ---- External Function Prototypes ------------------------------------- */ ++ ++extern void serdes_set_blk(uint eth_num, uint phyaddr, uint blk); ++extern void serdes_wr_reg(uint eth_num, uint phyaddr, uint reg, uint data); ++extern uint16 serdes_rd_reg(uint eth_num, uint phyaddr, uint reg); ++extern uint16 serdes_get_id(uint eth_num, uint phyaddr, uint off); ++extern void serdes_reset(uint eth_num, uint phyaddr); ++extern int serdes_reset_core(uint eth_num, uint phyaddr); ++extern int serdes_start_pll(uint eth_num, uint phyaddr); ++extern int serdes_init(uint eth_num, uint phyaddr); ++#if defined(CONFIG_SERDES_ASYMMETRIC_MODE) ++extern int serdes_speeddpx_set(uint eth_num, uint phyaddr, int speed, int fulldpx); ++extern int serdes_set_asym_mode(uint eth_num, uint phyaddr); ++#endif /* (defined(CONFIG_SERDES_ASYMMETRIC_MODE)) */ ++ ++#endif /* _bcm_iproc_serdes_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_serdes_def.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_serdes_def.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_serdes_def.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_serdes_def.h 2017-11-09 17:53:43.935301000 +0800 +@@ -0,0 +1,328 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * These are serdes defines ++ * ++ */ ++ ++#ifndef _PHY_XGXS16G_H_ ++#define _PHY_XGXS16G_H_ ++ ++/* macros */ ++ ++/* Macros ONLY used after initialization */ ++#define XGXS16G_2p5G_ID(id2) ((id2 & 0xff) == 0xf) ++ ++ ++/****************************************************************************/ ++/***** Starting below is auto-generated register macros from RDB files *****/ ++/****************************************************************************/ ++ ++/**************************************************************************** ++ * Core Enums. ++ ***************************************************************************/ ++ ++#define XGXS16G_IEEE0BLK_IEEECONTROL0r 0x00000000 ++#define XGXS16G_XGXSBLK0_XGXSCONTROLr 0x00008000 ++#define XGXS16G_XGXSBLK0_XGXSSTATUSr 0x00008001 ++#define XGXS16G_XGXSBLK0_MMDSELECTr 0x0000800d ++#define XGXS16G_XGXSBLK0_MISCCONTROL1r 0x0000800e ++#define XGXS16G_XGXSBLK1_LANECTRL0r 0x00008015 ++#define XGXS16G_XGXSBLK1_LANECTRL1r 0x00008016 ++#define XGXS16G_XGXSBLK1_LANECTRL3r 0x00008018 ++#define XGXS16G_TX0_TX_ACONTROL0r 0x00008061 ++#define XGXS16G_RX0_RX_CONTROLr 0x000080b1 ++#define XGXS16G_AN73_PDET_PARDET10GCONTROLr 0x00008131 ++#define XGXS16G_XGXSBLK7_EEECONTROLr 0x00008150 ++#define XGXS16G_TX_LN_SWAP1r 0x00008169 ++#define XGXS16G_SERDESDIGITAL_CONTROL1000X1r 0x00008300 ++#define XGXS16G_SERDESDIGITAL_CONTROL1000X2r 0x00008301 ++#define XGXS16G_SERDESDIGITAL_CONTROL1000X3r 0x00008302 ++#define XGXS16G_SERDESDIGITAL_STATUS1000X1r 0x00008304 ++#define XGXS16G_SERDESDIGITAL_MISC1r 0x00008308 ++#define XGXS16G_SERDESID_SERDESID0r 0x00008310 ++#define XGXS16G_SERDESID_SERDESID1r 0x00008311 ++#define XGXS16G_SERDESID_SERDESID2r 0x00008312 ++#define XGXS16G_SERDESID_SERDESID3r 0x00008313 ++#define XGXS16G_REMOTEPHY_MISC3r 0x0000833c ++#define XGXS16G_REMOTEPHY_MISC5r 0x0000833e ++#define XGXS16G_BAM_NEXTPAGE_MP5_NEXTPAGECTRLr 0x00008350 ++#define XGXS16G_BAM_NEXTPAGE_UD_FIELDr 0x00008357 ++#define XGXS16G_COMBO_IEEE0_MIICNTLr 0x0000ffe0 ++#define XGXS16G_COMBO_IEEE0_AUTONEGADVr 0x0000ffe4 ++ ++#define WC40_DIGITAL4_MISC3r 0x0000833c ++ ++/* Digital4 :: Misc3 :: laneDisable [06:06] */ ++#define DIGITAL4_MISC3_LANEDISABLE_MASK 0x0040 ++#define DIGITAL4_MISC3_LANEDISABLE_ALIGN 0 ++#define DIGITAL4_MISC3_LANEDISABLE_BITS 1 ++#define DIGITAL4_MISC3_LANEDISABLE_SHIFT 6 ++ ++ ++/**************************************************************************** ++ * XGXS16G_IEEE_ieee0Blk ++ ***************************************************************************/ ++/**************************************************************************** ++ * ieee0Blk :: ieeeControl0 ++ ***************************************************************************/ ++/* ieee0Blk :: ieeeControl0 :: rst_hw [15:15] */ ++#define IEEE0BLK_IEEECONTROL0_RST_HW_MASK 0x8000 ++#define IEEE0BLK_IEEECONTROL0_RST_HW_ALIGN 0 ++#define IEEE0BLK_IEEECONTROL0_RST_HW_BITS 1 ++#define IEEE0BLK_IEEECONTROL0_RST_HW_SHIFT 15 ++ ++/* ieee0Blk :: ieeeControl0 :: gloopback [14:14] */ ++#define IEEE0BLK_IEEECONTROL0_GLOOPBACK_MASK 0x4000 ++#define IEEE0BLK_IEEECONTROL0_GLOOPBACK_ALIGN 0 ++#define IEEE0BLK_IEEECONTROL0_GLOOPBACK_BITS 1 ++#define IEEE0BLK_IEEECONTROL0_GLOOPBACK_SHIFT 14 ++ ++ ++/**************************************************************************** ++ * XGXS16G_USER_XgxsBlk0 ++ ***************************************************************************/ ++/**************************************************************************** ++ * XgxsBlk0 :: xgxsControl ++ ***************************************************************************/ ++/* XgxsBlk0 :: xgxsControl :: start_sequencer [13:13] */ ++#define XGXSBLK0_XGXSCONTROL_START_SEQUENCER_MASK 0x2000 ++#define XGXSBLK0_XGXSCONTROL_START_SEQUENCER_ALIGN 0 ++#define XGXSBLK0_XGXSCONTROL_START_SEQUENCER_BITS 1 ++#define XGXSBLK0_XGXSCONTROL_START_SEQUENCER_SHIFT 13 ++ ++/* XgxsBlk0 :: xgxsControl :: mode_10g [11:08] */ ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_MASK 0x0f00 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_ALIGN 0 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_BITS 4 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_SHIFT 8 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_XGXS 0 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_XGXS_noCC 1 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_IndLane 6 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_XGXS_noLss 8 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_XGXS_noLss_noCC 9 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_protBypass 10 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_protBypass_noDsk 11 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_ComboCoreMode 12 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_ClocksOff 15 ++ ++/* XgxsBlk0 :: xgxsControl :: hstl [05:05] */ ++#define XGXSBLK0_XGXSCONTROL_HSTL_MASK 0x0020 ++#define XGXSBLK0_XGXSCONTROL_HSTL_ALIGN 0 ++#define XGXSBLK0_XGXSCONTROL_HSTL_BITS 1 ++#define XGXSBLK0_XGXSCONTROL_HSTL_SHIFT 5 ++ ++/* XgxsBlk0 :: xgxsControl :: cdet_en [03:03] */ ++#define XGXSBLK0_XGXSCONTROL_CDET_EN_MASK 0x0008 ++#define XGXSBLK0_XGXSCONTROL_CDET_EN_ALIGN 0 ++#define XGXSBLK0_XGXSCONTROL_CDET_EN_BITS 1 ++#define XGXSBLK0_XGXSCONTROL_CDET_EN_SHIFT 3 ++ ++/* XgxsBlk0 :: xgxsControl :: eden [02:02] */ ++#define XGXSBLK0_XGXSCONTROL_EDEN_MASK 0x0004 ++#define XGXSBLK0_XGXSCONTROL_EDEN_ALIGN 0 ++#define XGXSBLK0_XGXSCONTROL_EDEN_BITS 1 ++#define XGXSBLK0_XGXSCONTROL_EDEN_SHIFT 2 ++ ++/* XgxsBlk0 :: xgxsControl :: afrst_en [01:01] */ ++#define XGXSBLK0_XGXSCONTROL_AFRST_EN_MASK 0x0002 ++#define XGXSBLK0_XGXSCONTROL_AFRST_EN_ALIGN 0 ++#define XGXSBLK0_XGXSCONTROL_AFRST_EN_BITS 1 ++#define XGXSBLK0_XGXSCONTROL_AFRST_EN_SHIFT 1 ++ ++/* XgxsBlk0 :: xgxsControl :: txcko_div [00:00] */ ++#define XGXSBLK0_XGXSCONTROL_TXCKO_DIV_MASK 0x0001 ++#define XGXSBLK0_XGXSCONTROL_TXCKO_DIV_ALIGN 0 ++#define XGXSBLK0_XGXSCONTROL_TXCKO_DIV_BITS 1 ++#define XGXSBLK0_XGXSCONTROL_TXCKO_DIV_SHIFT 0 ++ ++ ++/**************************************************************************** ++ * XgxsBlk0 :: xgxsStatus ++ ***************************************************************************/ ++/* XgxsBlk0 :: xgxsStatus :: txpll_lock [11:11] */ ++#define XGXSBLK0_XGXSSTATUS_TXPLL_LOCK_MASK 0x0800 ++#define XGXSBLK0_XGXSSTATUS_TXPLL_LOCK_ALIGN 0 ++#define XGXSBLK0_XGXSSTATUS_TXPLL_LOCK_BITS 1 ++#define XGXSBLK0_XGXSSTATUS_TXPLL_LOCK_SHIFT 11 ++ ++ ++/**************************************************************************** ++ * XgxsBlk0 :: miscControl1 ++ ***************************************************************************/ ++/* XgxsBlk0 :: miscControl1 :: PCS_dev_en_override [10:10] */ ++#define XGXSBLK0_MISCCONTROL1_PCS_DEV_EN_OVERRIDE_MASK 0x0400 ++#define XGXSBLK0_MISCCONTROL1_PCS_DEV_EN_OVERRIDE_ALIGN 0 ++#define XGXSBLK0_MISCCONTROL1_PCS_DEV_EN_OVERRIDE_BITS 1 ++#define XGXSBLK0_MISCCONTROL1_PCS_DEV_EN_OVERRIDE_SHIFT 10 ++ ++/* XgxsBlk0 :: miscControl1 :: PMD_dev_en_override [09:09] */ ++#define XGXSBLK0_MISCCONTROL1_PMD_DEV_EN_OVERRIDE_MASK 0x0200 ++#define XGXSBLK0_MISCCONTROL1_PMD_DEV_EN_OVERRIDE_ALIGN 0 ++#define XGXSBLK0_MISCCONTROL1_PMD_DEV_EN_OVERRIDE_BITS 1 ++#define XGXSBLK0_MISCCONTROL1_PMD_DEV_EN_OVERRIDE_SHIFT 9 ++ ++/* XgxsBlk0 :: miscControl1 :: ieee_blksel_autodet [01:01] */ ++#define XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_AUTODET_MASK 0x0002 ++#define XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_AUTODET_ALIGN 0 ++#define XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_AUTODET_BITS 1 ++#define XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_AUTODET_SHIFT 1 ++ ++/* XgxsBlk0 :: miscControl1 :: ieee_blksel_val [00:00] */ ++#define XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_VAL_MASK 0x0001 ++#define XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_VAL_ALIGN 0 ++#define XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_VAL_BITS 1 ++#define XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_VAL_SHIFT 0 ++ ++ ++/**************************************************************************** ++ * XGXS16G_USER_XgxsBlk1 ++ ***************************************************************************/ ++/**************************************************************************** ++ * XgxsBlk1 :: laneCtrl0 ++ ***************************************************************************/ ++/* XgxsBlk1 :: laneCtrl0 :: cl36_pcs_en_rx [07:04] */ ++#define XGXSBLK1_LANECTRL0_CL36_PCS_EN_RX_MASK 0x00f0 ++#define XGXSBLK1_LANECTRL0_CL36_PCS_EN_RX_ALIGN 0 ++#define XGXSBLK1_LANECTRL0_CL36_PCS_EN_RX_BITS 4 ++#define XGXSBLK1_LANECTRL0_CL36_PCS_EN_RX_SHIFT 4 ++ ++/* XgxsBlk1 :: laneCtrl0 :: cl36_pcs_en_tx [03:00] */ ++#define XGXSBLK1_LANECTRL0_CL36_PCS_EN_TX_MASK 0x000f ++#define XGXSBLK1_LANECTRL0_CL36_PCS_EN_TX_ALIGN 0 ++#define XGXSBLK1_LANECTRL0_CL36_PCS_EN_TX_BITS 4 ++#define XGXSBLK1_LANECTRL0_CL36_PCS_EN_TX_SHIFT 0 ++ ++ ++/**************************************************************************** ++ * XGXS16G_USER_TX0 ++ ***************************************************************************/ ++/**************************************************************************** ++ * TX0 :: Tx_AControl0 ++ ***************************************************************************/ ++/* TX0 :: Tx_AControl0 :: txpol_flip [05:05] */ ++#define TX0_TX_ACONTROL0_TXPOL_FLIP_MASK 0x0020 ++#define TX0_TX_ACONTROL0_TXPOL_FLIP_ALIGN 0 ++#define TX0_TX_ACONTROL0_TXPOL_FLIP_BITS 1 ++#define TX0_TX_ACONTROL0_TXPOL_FLIP_SHIFT 5 ++ ++ ++/**************************************************************************** ++ * XGXS16G_USER_dsc_2_0 ++ ***************************************************************************/ ++/**************************************************************************** ++ * dsc_2_0 :: dsc_ctrl0 ++ ***************************************************************************/ ++/* dsc_2_0 :: dsc_ctrl0 :: rxSeqStart [15:15] */ ++#define DSC_2_0_DSC_CTRL0_RXSEQSTART_MASK 0x8000 ++#define DSC_2_0_DSC_CTRL0_RXSEQSTART_ALIGN 0 ++#define DSC_2_0_DSC_CTRL0_RXSEQSTART_BITS 1 ++#define DSC_2_0_DSC_CTRL0_RXSEQSTART_SHIFT 15 ++ ++ ++/**************************************************************************** ++ * XGXS16G_USER_SerdesDigital ++ ***************************************************************************/ ++/**************************************************************************** ++ * SerdesDigital :: Control1000X1 ++ ***************************************************************************/ ++/* SerdesDigital :: Control1000X1 :: crc_checker_disable [07:07] */ ++#define SERDESDIGITAL_CONTROL1000X1_CRC_CHECKER_DISABLE_MASK 0x0080 ++#define SERDESDIGITAL_CONTROL1000X1_CRC_CHECKER_DISABLE_ALIGN 0 ++#define SERDESDIGITAL_CONTROL1000X1_CRC_CHECKER_DISABLE_BITS 1 ++#define SERDESDIGITAL_CONTROL1000X1_CRC_CHECKER_DISABLE_SHIFT 7 ++ ++/* SerdesDigital :: Control1000X1 :: disable_pll_pwrdwn [06:06] */ ++#define SERDESDIGITAL_CONTROL1000X1_DISABLE_PLL_PWRDWN_MASK 0x0040 ++#define SERDESDIGITAL_CONTROL1000X1_DISABLE_PLL_PWRDWN_ALIGN 0 ++#define SERDESDIGITAL_CONTROL1000X1_DISABLE_PLL_PWRDWN_BITS 1 ++#define SERDESDIGITAL_CONTROL1000X1_DISABLE_PLL_PWRDWN_SHIFT 6 ++ ++/* SerdesDigital :: Control1000X1 :: fiber_mode_1000X [00:00] */ ++#define SERDESDIGITAL_CONTROL1000X1_FIBER_MODE_1000X_MASK 0x0001 ++#define SERDESDIGITAL_CONTROL1000X1_FIBER_MODE_1000X_ALIGN 0 ++#define SERDESDIGITAL_CONTROL1000X1_FIBER_MODE_1000X_BITS 1 ++#define SERDESDIGITAL_CONTROL1000X1_FIBER_MODE_1000X_SHIFT 0 ++ ++/**************************************************************************** ++ * SerdesDigital :: Control1000X3 ++ ***************************************************************************/ ++/* SerdesDigital :: Control1000X3 :: fifo_elasicity_tx_rx [02:01] */ ++#define SERDESDIGITAL_CONTROL1000X3_FIFO_ELASICITY_TX_RX_MASK 0x0006 ++#define SERDESDIGITAL_CONTROL1000X3_FIFO_ELASICITY_TX_RX_ALIGN 0 ++#define SERDESDIGITAL_CONTROL1000X3_FIFO_ELASICITY_TX_RX_BITS 2 ++#define SERDESDIGITAL_CONTROL1000X3_FIFO_ELASICITY_TX_RX_SHIFT 1 ++ ++/* SerdesDigital :: Control1000X3 :: tx_fifo_rst [00:00] */ ++#define SERDESDIGITAL_CONTROL1000X3_TX_FIFO_RST_MASK 0x0001 ++#define SERDESDIGITAL_CONTROL1000X3_TX_FIFO_RST_ALIGN 0 ++#define SERDESDIGITAL_CONTROL1000X3_TX_FIFO_RST_BITS 1 ++#define SERDESDIGITAL_CONTROL1000X3_TX_FIFO_RST_SHIFT 0 ++ ++/**************************************************************************** ++ * SerdesDigital :: Status1000X1 ++ ***************************************************************************/ ++/* SerdesDigital :: Status1000X1 :: speed_status [04:03] */ ++#define SERDESDIGITAL_STATUS1000X1_SPEED_STATUS_MASK 0x0018 ++#define SERDESDIGITAL_STATUS1000X1_SPEED_STATUS_ALIGN 0 ++#define SERDESDIGITAL_STATUS1000X1_SPEED_STATUS_BITS 2 ++#define SERDESDIGITAL_STATUS1000X1_SPEED_STATUS_SHIFT 3 ++ ++/**************************************************************************** ++ * SerdesDigital :: Misc1 ++ ***************************************************************************/ ++/* SerdesDigital :: Misc1 :: refclk_sel [15:13] */ ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_MASK 0xe000 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_ALIGN 0 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_BITS 3 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_SHIFT 13 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_clk_25MHz 0 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_clk_100MHz 1 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_clk_125MHz 2 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_clk_156p25MHz 3 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_clk_187p5MHz 4 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_clk_161p25Mhz 5 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_clk_50Mhz 6 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_clk_106p25Mhz 7 ++ ++/* SerdesDigital :: Misc1 :: force_speed_sel [04:04] */ ++#define SERDESDIGITAL_MISC1_FORCE_SPEED_SEL_MASK 0x0010 ++#define SERDESDIGITAL_MISC1_FORCE_SPEED_SEL_ALIGN 0 ++#define SERDESDIGITAL_MISC1_FORCE_SPEED_SEL_BITS 1 ++#define SERDESDIGITAL_MISC1_FORCE_SPEED_SEL_SHIFT 4 ++ ++/* SerdesDigital :: Misc1 :: force_speed [03:00] */ ++#define SERDESDIGITAL_MISC1_FORCE_SPEED_MASK 0x000f ++#define SERDESDIGITAL_MISC1_FORCE_SPEED_ALIGN 0 ++#define SERDESDIGITAL_MISC1_FORCE_SPEED_BITS 4 ++#define SERDESDIGITAL_MISC1_FORCE_SPEED_SHIFT 0 ++ ++ ++/**************************************************************************** ++ * CL73_UserB0 :: CL73_BAMCtrl1 ++ ***************************************************************************/ ++/* CL73_UserB0 :: CL73_BAMCtrl1 :: CL73_bamEn [15:15] */ ++#define CL73_USERB0_CL73_BAMCTRL1_CL73_BAMEN_MASK 0x8000 ++#define CL73_USERB0_CL73_BAMCTRL1_CL73_BAMEN_ALIGN 0 ++#define CL73_USERB0_CL73_BAMCTRL1_CL73_BAMEN_BITS 1 ++#define CL73_USERB0_CL73_BAMCTRL1_CL73_BAMEN_SHIFT 15 ++ ++ ++/**************************************************************************** ++ * Datatype Definitions. ++ ***************************************************************************/ ++#endif /* _PHY_XGXS16G_H_ */ ++ ++/* End of File */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmnvram.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmnvram.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmnvram.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmnvram.h 2017-11-09 17:53:43.936309000 +0800 +@@ -0,0 +1,290 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * NVRAM variable manipulation ++ * ++ * $Id: bcmnvram.h 325984 2012-04-05 08:51:37Z $ ++ */ ++ ++#ifndef _bcmnvram_h_ ++#define _bcmnvram_h_ ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++#include ++#include ++#include ++ ++struct nvram_header { ++ uint32 magic; ++ uint32 len; ++ uint32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */ ++ uint32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */ ++ uint32 config_ncdl; /* ncdl values for memc */ ++}; ++ ++struct nvram_otphdr { ++ struct nvram_header nvh; ++ uint16 flags_swmacm_gpio_phya; /* otp flags, switch/gmac mode, gpio, phyaddr */ ++ struct ether_addr mac; ++ uint32 clkfreq; ++}; ++ ++struct nvram_tuple { ++ char *name; ++ char *value; ++ struct nvram_tuple *next; ++}; ++ ++/* ++ * Get default value for an NVRAM variable ++ */ ++extern char *nvram_default_get(const char *name); ++ ++/* ++ * Initialize NVRAM access. May be unnecessary or undefined on certain ++ * platforms. ++ */ ++extern int nvram_init(void *sih); ++ ++/* ++ * Append a chunk of nvram variables to the global list ++ */ ++extern int nvram_append(void *si, char *vars, uint varsz); ++ ++extern void nvram_get_global_vars(char **varlst, uint *varsz); ++ ++ ++/* ++ * Check for reset button press for restoring factory defaults. ++ */ ++extern int nvram_reset(void *sih); ++ ++/* ++ * Disable NVRAM access. May be unnecessary or undefined on certain ++ * platforms. ++ */ ++extern void nvram_exit(void *sih); ++ ++/* ++ * Get the value of an NVRAM variable. The pointer returned may be ++ * invalid after a set. ++ * @param name name of variable to get ++ * @return value of variable or NULL if undefined ++ */ ++extern char * nvram_get(const char *name); ++ ++/* ++ * Read the reset GPIO value from the nvram and set the GPIO ++ * as input ++ */ ++extern int BCMINITFN(nvram_resetgpio_init)(void *sih); ++ ++/* ++ * Get the value of an NVRAM variable. ++ * @param name name of variable to get ++ * @return value of variable or NUL if undefined ++ */ ++static INLINE char * ++nvram_safe_get(const char *name) ++{ ++ char *p = nvram_get(name); ++ return p ? p : ""; ++} ++ ++/* ++ * Match an NVRAM variable. ++ * @param name name of variable to match ++ * @param match value to compare against value of variable ++ * @return TRUE if variable is defined and its value is string equal ++ * to match or FALSE otherwise ++ */ ++static INLINE int ++nvram_match(char *name, char *match) ++{ ++ const char *value = nvram_get(name); ++ return (value && !strcmp(value, match)); ++} ++ ++/* ++ * Inversely match an NVRAM variable. ++ * @param name name of variable to match ++ * @param match value to compare against value of variable ++ * @return TRUE if variable is defined and its value is not string ++ * equal to invmatch or FALSE otherwise ++ */ ++static INLINE int ++nvram_invmatch(char *name, char *invmatch) ++{ ++ const char *value = nvram_get(name); ++ return (value && strcmp(value, invmatch)); ++} ++ ++/* ++ * Set the value of an NVRAM variable. The name and value strings are ++ * copied into private storage. Pointers to previously set values ++ * may become invalid. The new value may be immediately ++ * retrieved but will not be permanently stored until a commit. ++ * @param name name of variable to set ++ * @param value value of variable ++ * @return 0 on success and errno on failure ++ */ ++extern int nvram_set(const char *name, const char *value); ++ ++/* ++ * Unset an NVRAM variable. Pointers to previously set values ++ * remain valid until a set. ++ * @param name name of variable to unset ++ * @return 0 on success and errno on failure ++ * NOTE: use nvram_commit to commit this change to flash. ++ */ ++extern int nvram_unset(const char *name); ++ ++/* ++ * NVRAM is based of FLASH or OTP. ++ * @return From FLASH: TRUE ++ * From OTP: FALSE ++ */ ++extern bool nvram_inotp(void); ++ ++/* ++ * Commit NVRAM header to OTP. All pointers to values ++ * may be invalid after a commit. ++ * NVRAM values are undefined after a commit. ++ * @return 0 on success and errno on failure ++ */ ++extern int nvram_otpcommit(void *sih); ++ ++/* ++ * Commit NVRAM variables to permanent storage. All pointers to values ++ * may be invalid after a commit. ++ * NVRAM values are undefined after a commit. ++ * @return 0 on success and errno on failure ++ */ ++extern int nvram_commit(void); ++ ++/* ++ * Get all NVRAM variables (format name=value\0 ... \0\0). ++ * @param buf buffer to store variables ++ * @param count size of buffer in bytes ++ * @return 0 on success and errno on failure ++ */ ++extern int nvram_getall(char *nvram_buf, int count); ++ ++/* ++ * returns the crc value of the nvram ++ * @param nvh nvram header pointer ++ */ ++uint8 nvram_calc_crc(struct nvram_header * nvh); ++ ++#endif /* _LANGUAGE_ASSEMBLY */ ++ ++/* The NVRAM version number stored as an NVRAM variable */ ++#define NVRAM_SOFTWARE_VERSION "1" ++ ++#define NVRAM_MAGIC 0x48534C46 /* 'FLSH' */ ++#define NVRAM_CLEAR_MAGIC 0x0 ++#define NVRAM_INVALID_MAGIC 0xFFFFFFFF ++#define NVRAM_VERSION 1 ++#define NVRAM_HEADER_SIZE 20 ++#define NVRAM_SPACE 0x8000 ++#define ENVRAM_SPACE 0x1000 ++ ++#define NVRAM_MAX_VALUE_LEN 255 ++#define NVRAM_MAX_PARAM_LEN 64 ++ ++#define NVRAM_CRC_START_POSITION 9 /* magic, len, crc8 to be skipped */ ++#define NVRAM_CRC_VER_MASK 0xffffff00 /* for crc_ver_init */ ++ ++/* Incase of nvram header(in OTP), we save 16bit after nvram header ++ * o 0:0 Switch Present ++ * o 1:4 Switch and gmac mode ++ * o 5:10 robo reset GPIO pin number ++ * o 11:15 phyaddr ++ */ ++#define OTPNVRAM_SWITCH_PRESENT 0x1 ++ ++#define OTPNVRAM_FLAGS_MASK 0x1 ++#define OTPNVRAM_SMACMODE_MASK 0x1e ++#define OTPNVRAM_GPIO_MASK 0x7e0 ++#define OTPNVRAM_PHYADDR_MASK 0xf800 ++ ++#define OTPNVRAM_SMACMODE_SHIFT 1 ++#define OTPNVRAM_GPIO_SHIFT 5 ++#define OTPNVRAM_PHYADDR_SHIFT 11 ++ ++/* clkfreq is saved in following format in OTP nvram data ++ * 9:0 pci clock ++ * 20:10 si clock ++ * 31:21 mips clock ++ */ ++ ++#define NVRAM_PCI_CLKMASK 0x3ff ++#define NVRAM_SI_CLKMASK 0x1ffc00 ++#define NVRAM_SI_CLKSHIFT 10 ++#define NVRAM_CPUCLK_SHIFT 21 ++ ++/* Offsets to embedded nvram area */ ++#define NVRAM_START_COMPRESSED 0x400 ++#define NVRAM_START 0x1000 ++ ++#define BCM_JUMBO_NVRAM_DELIMIT '\n' ++#define BCM_JUMBO_START "Broadcom Jumbo Nvram file" ++ ++#if (defined(FAILSAFE_UPGRADE) || defined(CONFIG_FAILSAFE_UPGRADE) || \ ++ defined(__CONFIG_FAILSAFE_UPGRADE_SUPPORT__)) ++#define IMAGE_SIZE "image_size" ++#define BOOTPARTITION "bootpartition" ++#define IMAGE_BOOT BOOTPARTITION ++#define PARTIALBOOTS "partialboots" ++#define MAXPARTIALBOOTS "maxpartialboots" ++#define IMAGE_1ST_FLASH_TRX "flash0.trx" ++#define IMAGE_1ST_FLASH_OS "flash0.os" ++#define IMAGE_2ND_FLASH_TRX "flash0.trx2" ++#define IMAGE_2ND_FLASH_OS "flash0.os2" ++#define IMAGE_FIRST_OFFSET "image_first_offset" ++#define IMAGE_SECOND_OFFSET "image_second_offset" ++#define LINUX_FIRST "linux" ++#define LINUX_SECOND "linux2" ++#endif ++ ++#if (defined(DUAL_IMAGE) || defined(CONFIG_DUAL_IMAGE) || \ ++ defined(__CONFIG_DUAL_IMAGE_FLASH_SUPPORT__)) ++/* Shared by all: CFE, Linux Kernel, and Ap */ ++#define IMAGE_BOOT "image_boot" ++#define BOOTPARTITION IMAGE_BOOT ++/* CFE variables */ ++#define IMAGE_1ST_FLASH_TRX "flash0.trx" ++#define IMAGE_1ST_FLASH_OS "flash0.os" ++#define IMAGE_2ND_FLASH_TRX "flash0.trx2" ++#define IMAGE_2ND_FLASH_OS "flash0.os2" ++#define IMAGE_SIZE "image_size" ++ ++/* CFE and Linux Kernel shared variables */ ++#define IMAGE_FIRST_OFFSET "image_first_offset" ++#define IMAGE_SECOND_OFFSET "image_second_offset" ++ ++/* Linux application variables */ ++#define LINUX_FIRST "linux" ++#define LINUX_SECOND "linux2" ++#define POLICY_TOGGLE "toggle" ++#define LINUX_PART_TO_FLASH "linux_to_flash" ++#define LINUX_FLASH_POLICY "linux_flash_policy" ++ ++#endif /* defined(DUAL_IMAGE||CONFIG_DUAL_IMAGE)||__CONFIG_DUAL_IMAGE_FLASH_SUPPORT__ */ ++ ++int nvram_env_gmac_name(int gmac, char *name); ++ ++#endif /* _bcmnvram_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmparams.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmparams.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmparams.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmparams.h 2017-11-09 17:53:43.937301000 +0800 +@@ -0,0 +1,32 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Misc system wide parameters. ++ * ++ * $Id: bcmparams.h 241182 2011-02-17 21:50:03Z $ ++ */ ++ ++#ifndef _bcmparams_h_ ++#define _bcmparams_h_ ++ ++#define VLAN_MAXVID 15 /* Max. VLAN ID supported/allowed */ ++ ++#define VLAN_NUMPRIS 8 /* # of prio, start from 0 */ ++ ++#define DEV_NUMIFS 16 /* Max. # of devices/interfaces supported */ ++ ++#define WL_MAXBSSCFG 16 /* maximum number of BSS Configs we can configure */ ++ ++#endif +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmperf.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmperf.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmperf.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmperf.h 2017-11-09 17:53:43.938295000 +0800 +@@ -0,0 +1,40 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Performance counters software interface. ++ * ++ * $Id: bcmperf.h 241182 2011-02-17 21:50:03Z $ ++ */ ++/* essai */ ++#ifndef _BCMPERF_H_ ++#define _BCMPERF_H_ ++/* get cache hits and misses */ ++#if defined(BCMMIPS) && defined(BCMPERFSTATS) ++#include ++#define BCMPERF_ENABLE_INSTRCOUNT() hndmips_perf_instrcount_enable() ++#define BCMPERF_ENABLE_ICACHE_MISS() hndmips_perf_icache_miss_enable() ++#define BCMPERF_ENABLE_ICACHE_HIT() hndmips_perf_icache_hit_enable() ++#define BCMPERF_GETICACHE_MISS(x) ((x) = hndmips_perf_read_cache_miss()) ++#define BCMPERF_GETICACHE_HIT(x) ((x) = hndmips_perf_read_cache_hit()) ++#define BCMPERF_GETINSTRCOUNT(x) ((x) = hndmips_perf_read_instrcount()) ++#else ++#define BCMPERF_ENABLE_INSTRCOUNT() ++#define BCMPERF_ENABLE_ICACHE_MISS() ++#define BCMPERF_ENABLE_ICACHE_HIT() ++#define BCMPERF_GETICACHE_MISS(x) ((x) = 0) ++#define BCMPERF_GETICACHE_HIT(x) ((x) = 0) ++#define BCMPERF_GETINSTRCOUNT(x) ((x) = 0) ++#endif /* defined(mips) */ ++#endif /* _BCMPERF_H_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmsdpcm.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmsdpcm.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmsdpcm.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmsdpcm.h 2017-11-09 17:53:43.939297000 +0800 +@@ -0,0 +1,268 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Broadcom SDIO/PCMCIA ++ * Software-specific definitions shared between device and host side ++ * ++ * $Id: bcmsdpcm.h 314495 2012-02-12 07:56:39Z $ ++ */ ++ ++#ifndef _bcmsdpcm_h_ ++#define _bcmsdpcm_h_ ++ ++/* ++ * Software allocation of To SB Mailbox resources ++ */ ++ ++/* intstatus bits */ ++#define I_SMB_NAK I_SMB_SW0 /* To SB Mailbox Frame NAK */ ++#define I_SMB_INT_ACK I_SMB_SW1 /* To SB Mailbox Host Interrupt ACK */ ++#define I_SMB_USE_OOB I_SMB_SW2 /* To SB Mailbox Use OOB Wakeup */ ++#define I_SMB_DEV_INT I_SMB_SW3 /* To SB Mailbox Miscellaneous Interrupt */ ++ ++#define I_TOSBMAIL (I_SMB_NAK | I_SMB_INT_ACK | I_SMB_USE_OOB | I_SMB_DEV_INT) ++ ++/* tosbmailbox bits corresponding to intstatus bits */ ++#define SMB_NAK (1 << 0) /* To SB Mailbox Frame NAK */ ++#define SMB_INT_ACK (1 << 1) /* To SB Mailbox Host Interrupt ACK */ ++#define SMB_USE_OOB (1 << 2) /* To SB Mailbox Use OOB Wakeup */ ++#define SMB_DEV_INT (1 << 3) /* To SB Mailbox Miscellaneous Interrupt */ ++#define SMB_MASK 0x0000000f /* To SB Mailbox Mask */ ++ ++/* tosbmailboxdata */ ++#define SMB_DATA_VERSION_MASK 0x00ff0000 /* host protocol version (sent with F2 enable) */ ++#define SMB_DATA_VERSION_SHIFT 16 /* host protocol version (sent with F2 enable) */ ++ ++/* ++ * Software allocation of To Host Mailbox resources ++ */ ++ ++/* intstatus bits */ ++#define I_HMB_FC_STATE I_HMB_SW0 /* To Host Mailbox Flow Control State */ ++#define I_HMB_FC_CHANGE I_HMB_SW1 /* To Host Mailbox Flow Control State Changed */ ++#define I_HMB_FRAME_IND I_HMB_SW2 /* To Host Mailbox Frame Indication */ ++#define I_HMB_HOST_INT I_HMB_SW3 /* To Host Mailbox Miscellaneous Interrupt */ ++ ++#define I_TOHOSTMAIL (I_HMB_FC_CHANGE | I_HMB_FRAME_IND | I_HMB_HOST_INT) ++ ++/* tohostmailbox bits corresponding to intstatus bits */ ++#define HMB_FC_ON (1 << 0) /* To Host Mailbox Flow Control State */ ++#define HMB_FC_CHANGE (1 << 1) /* To Host Mailbox Flow Control State Changed */ ++#define HMB_FRAME_IND (1 << 2) /* To Host Mailbox Frame Indication */ ++#define HMB_HOST_INT (1 << 3) /* To Host Mailbox Miscellaneous Interrupt */ ++#define HMB_MASK 0x0000000f /* To Host Mailbox Mask */ ++ ++/* tohostmailboxdata */ ++#define HMB_DATA_NAKHANDLED 0x01 /* we're ready to retransmit NAK'd frame to host */ ++#define HMB_DATA_DEVREADY 0x02 /* we're ready to to talk to host after enable */ ++#define HMB_DATA_FC 0x04 /* per prio flowcontrol update flag to host */ ++#define HMB_DATA_FWREADY 0x08 /* firmware is ready for protocol activity */ ++#define HMB_DATA_FWHALT 0x10 /* firmware has halted operation */ ++ ++#define HMB_DATA_FCDATA_MASK 0xff000000 /* per prio flowcontrol data */ ++#define HMB_DATA_FCDATA_SHIFT 24 /* per prio flowcontrol data */ ++ ++#define HMB_DATA_VERSION_MASK 0x00ff0000 /* device protocol version (with devready) */ ++#define HMB_DATA_VERSION_SHIFT 16 /* device protocol version (with devready) */ ++ ++/* ++ * Software-defined protocol header ++ */ ++ ++/* Current protocol version */ ++#define SDPCM_PROT_VERSION 4 ++ ++/* SW frame header */ ++#define SDPCM_SEQUENCE_MASK 0x000000ff /* Sequence Number Mask */ ++#define SDPCM_PACKET_SEQUENCE(p) (((uint8 *)p)[0] & 0xff) /* p starts w/SW Header */ ++ ++#define SDPCM_CHANNEL_MASK 0x00000f00 /* Channel Number Mask */ ++#define SDPCM_CHANNEL_SHIFT 8 /* Channel Number Shift */ ++#define SDPCM_PACKET_CHANNEL(p) (((uint8 *)p)[1] & 0x0f) /* p starts w/SW Header */ ++ ++#define SDPCM_FLAGS_MASK 0x0000f000 /* Mask of flag bits */ ++#define SDPCM_FLAGS_SHIFT 12 /* Flag bits shift */ ++#define SDPCM_PACKET_FLAGS(p) ((((uint8 *)p)[1] & 0xf0) >> 4) /* p starts w/SW Header */ ++ ++/* Next Read Len: lookahead length of next frame, in 16-byte units (rounded up) */ ++#define SDPCM_NEXTLEN_MASK 0x00ff0000 /* Next Read Len Mask */ ++#define SDPCM_NEXTLEN_SHIFT 16 /* Next Read Len Shift */ ++#define SDPCM_NEXTLEN_VALUE(p) ((((uint8 *)p)[2] & 0xff) << 4) /* p starts w/SW Header */ ++#define SDPCM_NEXTLEN_OFFSET 2 ++ ++/* Data Offset from SOF (HW Tag, SW Tag, Pad) */ ++#define SDPCM_DOFFSET_OFFSET 3 /* Data Offset */ ++#define SDPCM_DOFFSET_VALUE(p) (((uint8 *)p)[SDPCM_DOFFSET_OFFSET] & 0xff) ++#define SDPCM_DOFFSET_MASK 0xff000000 ++#define SDPCM_DOFFSET_SHIFT 24 ++ ++#define SDPCM_FCMASK_OFFSET 4 /* Flow control */ ++#define SDPCM_FCMASK_VALUE(p) (((uint8 *)p)[SDPCM_FCMASK_OFFSET ] & 0xff) ++#define SDPCM_WINDOW_OFFSET 5 /* Credit based fc */ ++#define SDPCM_WINDOW_VALUE(p) (((uint8 *)p)[SDPCM_WINDOW_OFFSET] & 0xff) ++#define SDPCM_VERSION_OFFSET 6 /* Version # */ ++#define SDPCM_VERSION_VALUE(p) (((uint8 *)p)[SDPCM_VERSION_OFFSET] & 0xff) ++#define SDPCM_UNUSED_OFFSET 7 /* Spare */ ++#define SDPCM_UNUSED_VALUE(p) (((uint8 *)p)[SDPCM_UNUSED_OFFSET] & 0xff) ++ ++#define SDPCM_SWHEADER_LEN 8 /* SW header is 64 bits */ ++ ++/* logical channel numbers */ ++#define SDPCM_CONTROL_CHANNEL 0 /* Control Request/Response Channel Id */ ++#define SDPCM_EVENT_CHANNEL 1 /* Asyc Event Indication Channel Id */ ++#define SDPCM_DATA_CHANNEL 2 /* Data Xmit/Recv Channel Id */ ++#define SDPCM_GLOM_CHANNEL 3 /* For coalesced packets (superframes) */ ++#define SDPCM_TEST_CHANNEL 15 /* Reserved for test/debug packets */ ++#define SDPCM_MAX_CHANNEL 15 ++ ++#define SDPCM_SEQUENCE_WRAP 256 /* wrap-around val for eight-bit frame seq number */ ++ ++#define SDPCM_FLAG_RESVD0 0x01 ++#define SDPCM_FLAG_RESVD1 0x02 ++#define SDPCM_FLAG_GSPI_TXENAB 0x04 ++#define SDPCM_FLAG_GLOMDESC 0x08 /* Superframe descriptor mask */ ++ ++/* For GLOM_CHANNEL frames, use a flag to indicate descriptor frame */ ++#define SDPCM_GLOMDESC_FLAG (SDPCM_FLAG_GLOMDESC << SDPCM_FLAGS_SHIFT) ++ ++#define SDPCM_GLOMDESC(p) (((uint8 *)p)[1] & 0x80) ++ ++/* For TEST_CHANNEL packets, define another 4-byte header */ ++#define SDPCM_TEST_HDRLEN 4 /* Generally: Cmd(1), Ext(1), Len(2); ++ * Semantics of Ext byte depend on command. ++ * Len is current or requested frame length, not ++ * including test header; sent little-endian. ++ */ ++#define SDPCM_TEST_DISCARD 0x01 /* Receiver discards. Ext is a pattern id. */ ++#define SDPCM_TEST_ECHOREQ 0x02 /* Echo request. Ext is a pattern id. */ ++#define SDPCM_TEST_ECHORSP 0x03 /* Echo response. Ext is a pattern id. */ ++#define SDPCM_TEST_BURST 0x04 /* Receiver to send a burst. Ext is a frame count */ ++#define SDPCM_TEST_SEND 0x05 /* Receiver sets send mode. Ext is boolean on/off */ ++ ++/* Handy macro for filling in datagen packets with a pattern */ ++#define SDPCM_TEST_FILL(byteno, id) ((uint8)(id + byteno)) ++ ++/* ++ * Software counters (first part matches hardware counters) ++ */ ++ ++typedef volatile struct { ++ uint32 cmd52rd; /* Cmd52RdCount, SDIO: cmd52 reads */ ++ uint32 cmd52wr; /* Cmd52WrCount, SDIO: cmd52 writes */ ++ uint32 cmd53rd; /* Cmd53RdCount, SDIO: cmd53 reads */ ++ uint32 cmd53wr; /* Cmd53WrCount, SDIO: cmd53 writes */ ++ uint32 abort; /* AbortCount, SDIO: aborts */ ++ uint32 datacrcerror; /* DataCrcErrorCount, SDIO: frames w/CRC error */ ++ uint32 rdoutofsync; /* RdOutOfSyncCount, SDIO/PCMCIA: Rd Frm out of sync */ ++ uint32 wroutofsync; /* RdOutOfSyncCount, SDIO/PCMCIA: Wr Frm out of sync */ ++ uint32 writebusy; /* WriteBusyCount, SDIO: device asserted "busy" */ ++ uint32 readwait; /* ReadWaitCount, SDIO: no data ready for a read cmd */ ++ uint32 readterm; /* ReadTermCount, SDIO: read frame termination cmds */ ++ uint32 writeterm; /* WriteTermCount, SDIO: write frames termination cmds */ ++ uint32 rxdescuflo; /* receive descriptor underflows */ ++ uint32 rxfifooflo; /* receive fifo overflows */ ++ uint32 txfifouflo; /* transmit fifo underflows */ ++ uint32 runt; /* runt (too short) frames recv'd from bus */ ++ uint32 badlen; /* frame's rxh len does not match its hw tag len */ ++ uint32 badcksum; /* frame's hw tag chksum doesn't agree with len value */ ++ uint32 seqbreak; /* break in sequence # space from one rx frame to the next */ ++ uint32 rxfcrc; /* frame rx header indicates crc error */ ++ uint32 rxfwoos; /* frame rx header indicates write out of sync */ ++ uint32 rxfwft; /* frame rx header indicates write frame termination */ ++ uint32 rxfabort; /* frame rx header indicates frame aborted */ ++ uint32 woosint; /* write out of sync interrupt */ ++ uint32 roosint; /* read out of sync interrupt */ ++ uint32 rftermint; /* read frame terminate interrupt */ ++ uint32 wftermint; /* write frame terminate interrupt */ ++} sdpcmd_cnt_t; ++ ++/* ++ * Register Access Macros ++ */ ++ ++#define SDIODREV_IS(var, val) ((var) == (val)) ++#define SDIODREV_GE(var, val) ((var) >= (val)) ++#define SDIODREV_GT(var, val) ((var) > (val)) ++#define SDIODREV_LT(var, val) ((var) < (val)) ++#define SDIODREV_LE(var, val) ((var) <= (val)) ++ ++#define SDIODDMAREG32(h, dir, chnl) \ ++ ((dir) == DMA_TX ? \ ++ (void *)(uintptr)&((h)->regs->dma.sdiod32.dma32regs[chnl].xmt) : \ ++ (void *)(uintptr)&((h)->regs->dma.sdiod32.dma32regs[chnl].rcv)) ++ ++#define SDIODDMAREG64(h, dir, chnl) \ ++ ((dir) == DMA_TX ? \ ++ (void *)(uintptr)&((h)->regs->dma.sdiod64.dma64regs[chnl].xmt) : \ ++ (void *)(uintptr)&((h)->regs->dma.sdiod64.dma64regs[chnl].rcv)) ++ ++#define SDIODDMAREG(h, dir, chnl) \ ++ (SDIODREV_LT((h)->corerev, 1) ? \ ++ SDIODDMAREG32((h), (dir), (chnl)) : \ ++ SDIODDMAREG64((h), (dir), (chnl))) ++ ++#define PCMDDMAREG(h, dir, chnl) \ ++ ((dir) == DMA_TX ? \ ++ (void *)(uintptr)&((h)->regs->dma.pcm32.dmaregs.xmt) : \ ++ (void *)(uintptr)&((h)->regs->dma.pcm32.dmaregs.rcv)) ++ ++#define SDPCMDMAREG(h, dir, chnl, coreid) \ ++ ((coreid) == SDIOD_CORE_ID ? \ ++ SDIODDMAREG(h, dir, chnl) : \ ++ PCMDDMAREG(h, dir, chnl)) ++ ++#define SDIODFIFOREG(h, corerev) \ ++ (SDIODREV_LT((corerev), 1) ? \ ++ ((dma32diag_t *)(uintptr)&((h)->regs->dma.sdiod32.dmafifo)) : \ ++ ((dma32diag_t *)(uintptr)&((h)->regs->dma.sdiod64.dmafifo))) ++ ++#define PCMDFIFOREG(h) \ ++ ((dma32diag_t *)(uintptr)&((h)->regs->dma.pcm32.dmafifo)) ++ ++#define SDPCMFIFOREG(h, coreid, corerev) \ ++ ((coreid) == SDIOD_CORE_ID ? \ ++ SDIODFIFOREG(h, corerev) : \ ++ PCMDFIFOREG(h)) ++ ++/* ++ * Shared structure between dongle and the host. ++ * The structure contains pointers to trap or assert information. ++ */ ++#define SDPCM_SHARED_VERSION 0x0001 ++#define SDPCM_SHARED_VERSION_MASK 0x00FF ++#define SDPCM_SHARED_ASSERT_BUILT 0x0100 ++#define SDPCM_SHARED_ASSERT 0x0200 ++#define SDPCM_SHARED_TRAP 0x0400 ++#define SDPCM_SHARED_IN_BRPT 0x0800 ++#define SDPCM_SHARED_SET_BRPT 0x1000 ++#define SDPCM_SHARED_PENDING_BRPT 0x2000 ++ ++typedef struct { ++ uint32 flags; ++ uint32 trap_addr; ++ uint32 assert_exp_addr; ++ uint32 assert_file_addr; ++ uint32 assert_line; ++ uint32 console_addr; /* Address of hndrte_cons_t */ ++ uint32 msgtrace_addr; ++ uint32 fwid; ++} sdpcm_shared_t; ++ ++extern sdpcm_shared_t sdpcm_shared; ++ ++/* Function can be used to notify host of FW halt */ ++extern void sdpcmd_fwhalt(void); ++ ++#endif /* _bcmsdpcm_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmstdlib.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmstdlib.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmstdlib.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmstdlib.h 2017-11-09 17:53:43.940291000 +0800 +@@ -0,0 +1,128 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * prototypes for functions defined in bcmstdlib.c ++ * ++ * $Id: bcmstdlib.h 289936 2011-10-14 21:06:33Z $: ++ */ ++ ++/* ++ * bcmstdlib.h file should be used only to construct an OSL or alone without any OSL ++ * It should not be used with any orbitarary OSL's as there could be a conflict ++ * with some of the routines defined here. ++*/ ++ ++#ifndef _BCMSTDLIB_H ++#define _BCMSTDLIB_H ++ ++#include ++#include ++#include ++ ++#ifndef INT_MAX ++#define INT_MAX 2147483647 /* from limits.h */ ++#endif ++ ++ ++/* For backwards compatibility, define "BWL_NO_INTERNAL_STDLIB_SUPPORT" to ++ * exclude support for the BRCM stdlib APIs. This should be cleaned-up such ++ * that platforms that require the BRCM stdlib API should simply define ++ * "BWL_INTERNAL_STDLIB_SUPPORT". This would eliminate the need for the ++ * following #ifndef check. ++ */ ++#ifndef BWL_NO_INTERNAL_STDLIB_SUPPORT ++#define BWL_INTERNAL_STDLIB_SUPPORT ++#endif ++ ++#ifdef BWL_INTERNAL_STDLIB_SUPPORT ++/* This should be cleaned-up such that platforms that require the BRCM stdlib ++ * API should simply define "BWL_INTERNAL_STDLIB_SUPPORT". This would eliminate ++ * the need for the following #ifdef check. ++ */ ++#if !defined(_WIN32) && !defined(_CFE_) && !defined(EFI) ++ ++typedef int FILE; ++#define stdout ((FILE *)1) ++#define stderr ((FILE *)2) ++ ++/* i/o functions */ ++extern int fputc(int c, FILE *stream); ++extern void putc(int c); ++/* extern int putc(int c, FILE *stream); */ ++#define putchar(c) putc(c) ++extern int fputs(const char *s, FILE *stream); ++extern int puts(const char *s); ++extern int getc(void); ++extern bool keypressed(void); ++ ++/* bcopy, bcmp, and bzero */ ++#define bcopy(src, dst, len) memcpy((dst), (src), (len)) ++#define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) ++#define bzero(b, len) memset((b), '\0', (len)) ++ ++extern unsigned long rand(void); ++ ++#define atoi(s) ((int)(strtoul((s), NULL, 10))) ++ ++#endif ++ ++#if !defined(_WIN32) || defined(EFI) ++/* string functions */ ++#define PRINTF_BUFLEN 512 ++extern int printf(const char *fmt, ...) ++ __attribute__ ((format (__printf__, 1, 2))); ++extern int BCMROMFN(sprintf)(char *buf, const char *fmt, ...) ++ __attribute__ ((format (__printf__, 2, 3))); ++ ++extern int BCMROMFN(strcmp)(const char *s1, const char *s2); ++extern size_t BCMROMFN(strlen)(const char *s); ++extern char *BCMROMFN(strcpy)(char *dest, const char *src); ++extern char *BCMROMFN(strstr)(const char *s, const char *find); ++extern char *BCMROMFN(strncpy)(char *dest, const char *src, size_t n); ++extern char *BCMROMFN(strcat)(char *d, const char *s); ++ ++extern int BCMROMFN(strncmp)(const char *s1, const char *s2, size_t n); ++extern char *BCMROMFN(strchr)(const char *str, int c); ++extern char *BCMROMFN(strrchr)(const char *str, int c); ++extern size_t BCMROMFN(strspn)(const char *s1, const char *s2); ++extern size_t BCMROMFN(strcspn)(const char *s1, const char *s2); ++extern unsigned long BCMROMFN(strtoul)(const char *cp, char **endp, int base); ++#define strtol(nptr, endptr, base) ((long)strtoul((nptr), (endptr), (base))) ++ ++extern void *BCMROMFN(memmove)(void *dest, const void *src, size_t n); ++extern void *BCMROMFN(memchr)(const void *s, int c, size_t n); ++ ++extern int BCMROMFN(vsprintf)(char *buf, const char *fmt, va_list ap); ++/* mem functions */ ++/* For EFI, using EFIDriverLib versions */ ++/* Cannot use memmem in ROM because of character array initialization wiht "" in gcc */ ++extern void *memset(void *dest, int c, size_t n); ++/* Cannot use memcpy in ROM because of structure assignmnets in gcc */ ++extern void *memcpy(void *dest, const void *src, size_t n); ++extern int BCMROMFN(memcmp)(const void *s1, const void *s2, size_t n); ++ ++#endif /* !_WIN32 || EFI */ ++#endif /* BWL_INTERNAL_STDLIB_SUPPORT */ ++ ++#if !defined(_WIN32) || defined(EFI) ++extern int BCMROMFN(snprintf)(char *str, size_t n, char const *fmt, ...) ++ __attribute__ ((format (__printf__, 3, 4))); ++#else ++extern int BCMROMFN(snprintf)(char *str, size_t n, char const *fmt, ...); ++#endif ++ ++extern int BCMROMFN(vsnprintf)(char *buf, size_t size, const char *fmt, va_list ap); ++ ++#endif /* _BCMSTDLIB_H */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmutils.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmutils.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmutils.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmutils.h 2017-11-09 17:53:43.941299000 +0800 +@@ -0,0 +1,864 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Misc useful os-independent macros and functions. ++ * ++ * $Id: bcmutils.h 325951 2012-04-05 06:03:27Z $ ++ */ ++ ++#ifndef _bcmutils_h_ ++#define _bcmutils_h_ ++ ++#if defined(UNDER_CE) ++#include ++#else ++#define bcm_strcpy_s(dst, noOfElements, src) strcpy((dst), (src)) ++#define bcm_strncpy_s(dst, noOfElements, src, count) strncpy((dst), (src), (count)) ++#define bcm_strcat_s(dst, noOfElements, src) strcat((dst), (src)) ++#endif ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++#ifdef PKTQ_LOG ++#include ++#endif ++ ++/* ctype replacement */ ++#define _BCM_U 0x01 /* upper */ ++#define _BCM_L 0x02 /* lower */ ++#define _BCM_D 0x04 /* digit */ ++#define _BCM_C 0x08 /* cntrl */ ++#define _BCM_P 0x10 /* punct */ ++#define _BCM_S 0x20 /* white space (space/lf/tab) */ ++#define _BCM_X 0x40 /* hex digit */ ++#define _BCM_SP 0x80 /* hard space (0x20) */ ++ ++#if defined(BCMROMBUILD) ++extern const unsigned char BCMROMDATA(bcm_ctype)[]; ++#else ++extern const unsigned char bcm_ctype[]; ++#endif ++#define bcm_ismask(x) (bcm_ctype[(int)(unsigned char)(x)]) ++ ++#define bcm_isalnum(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L|_BCM_D)) != 0) ++#define bcm_isalpha(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L)) != 0) ++#define bcm_iscntrl(c) ((bcm_ismask(c)&(_BCM_C)) != 0) ++#define bcm_isdigit(c) ((bcm_ismask(c)&(_BCM_D)) != 0) ++#define bcm_isgraph(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D)) != 0) ++#define bcm_islower(c) ((bcm_ismask(c)&(_BCM_L)) != 0) ++#define bcm_isprint(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D|_BCM_SP)) != 0) ++#define bcm_ispunct(c) ((bcm_ismask(c)&(_BCM_P)) != 0) ++#define bcm_isspace(c) ((bcm_ismask(c)&(_BCM_S)) != 0) ++#define bcm_isupper(c) ((bcm_ismask(c)&(_BCM_U)) != 0) ++#define bcm_isxdigit(c) ((bcm_ismask(c)&(_BCM_D|_BCM_X)) != 0) ++#define bcm_tolower(c) (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c)) ++#define bcm_toupper(c) (bcm_islower((c)) ? ((c) + 'A' - 'a') : (c)) ++ ++/* Buffer structure for collecting string-formatted data ++* using bcm_bprintf() API. ++* Use bcm_binit() to initialize before use ++*/ ++ ++struct bcmstrbuf { ++ char *buf; /* pointer to current position in origbuf */ ++ unsigned int size; /* current (residual) size in bytes */ ++ char *origbuf; /* unmodified pointer to orignal buffer */ ++ unsigned int origsize; /* unmodified orignal buffer size in bytes */ ++}; ++ ++/* ** driver-only section ** */ ++#ifdef BCMDRIVER ++#ifdef EFI ++/* forward declare structyre type */ ++struct spktq; ++#endif ++#include ++ ++#define GPIO_PIN_NOTDEFINED 0x20 /* Pin not defined */ ++ ++/* ++ * Spin at most 'us' microseconds while 'exp' is true. ++ * Caller should explicitly test 'exp' when this completes ++ * and take appropriate error action if 'exp' is still true. ++ */ ++#define SPINWAIT(exp, us) { \ ++ uint countdown = (us) + 9; \ ++ while ((exp) && (countdown >= 10)) {\ ++ OSL_DELAY(10); \ ++ countdown -= 10; \ ++ } \ ++} ++ ++/* osl multi-precedence packet queue */ ++#ifndef PKTQ_LEN_DEFAULT ++#define PKTQ_LEN_DEFAULT 128 /* Max 128 packets */ ++#endif ++#ifndef PKTQ_MAX_PREC ++#define PKTQ_MAX_PREC 16 /* Maximum precedence levels */ ++#endif ++ ++typedef struct pktq_prec { ++ void *head; /* first packet to dequeue */ ++ void *tail; /* last packet to dequeue */ ++ uint16 len; /* number of queued packets */ ++ uint16 max; /* maximum number of queued packets */ ++} pktq_prec_t; ++ ++#ifdef PKTQ_LOG ++typedef struct { ++ uint32 requested; /* packets requested to be stored */ ++ uint32 stored; /* packets stored */ ++ uint32 saved; /* packets saved, ++ because a lowest priority queue has given away one packet ++ */ ++ uint32 selfsaved; /* packets saved, ++ because an older packet from the same queue has been dropped ++ */ ++ uint32 full_dropped; /* packets dropped, ++ because pktq is full with higher precedence packets ++ */ ++ uint32 dropped; /* packets dropped because pktq per that precedence is full */ ++ uint32 sacrificed; /* packets dropped, ++ in order to save one from a queue of a highest priority ++ */ ++ uint32 busy; /* packets droped because of hardware/transmission error */ ++ uint32 retry; /* packets re-sent because they were not received */ ++ uint32 ps_retry; /* packets retried again prior to moving power save mode */ ++ uint32 retry_drop; /* packets finally dropped after retry limit */ ++ uint32 max_avail; /* the high-water mark of the queue capacity for packets - ++ goes to zero as queue fills ++ */ ++ uint32 max_used; /* the high-water mark of the queue utilisation for packets - ++ increases with use ('inverse' of max_avail) ++ */ ++ uint32 queue_capacity; /* the maximum capacity of the queue */ ++} pktq_counters_t; ++#endif /* PKTQ_LOG */ ++ ++ ++#define PKTQ_COMMON \ ++ uint16 num_prec; /* number of precedences in use */ \ ++ uint16 hi_prec; /* rapid dequeue hint (>= highest non-empty prec) */ \ ++ uint16 max; /* total max packets */ \ ++ uint16 len; /* total number of packets */ ++ ++/* multi-priority pkt queue */ ++struct pktq { ++ PKTQ_COMMON ++ /* q array must be last since # of elements can be either PKTQ_MAX_PREC or 1 */ ++ struct pktq_prec q[PKTQ_MAX_PREC]; ++#ifdef PKTQ_LOG ++ pktq_counters_t _prec_cnt[PKTQ_MAX_PREC]; /* Counters per queue */ ++#endif ++}; ++ ++/* simple, non-priority pkt queue */ ++struct spktq { ++ PKTQ_COMMON ++ /* q array must be last since # of elements can be either PKTQ_MAX_PREC or 1 */ ++ struct pktq_prec q[1]; ++}; ++ ++#define PKTQ_PREC_ITER(pq, prec) for (prec = (pq)->num_prec - 1; prec >= 0; prec--) ++ ++/* fn(pkt, arg). return true if pkt belongs to if */ ++typedef bool (*ifpkt_cb_t)(void*, int); ++ ++#ifdef BCMPKTPOOL ++#define POOL_ENAB(pool) ((pool) && (pool)->inited) ++#if defined(BCM4329C0) ++#define SHARED_POOL (pktpool_shared_ptr) ++#else ++#define SHARED_POOL (pktpool_shared) ++#endif /* BCM4329C0 */ ++#else /* BCMPKTPOOL */ ++#define POOL_ENAB(bus) 0 ++#define SHARED_POOL ((struct pktpool *)NULL) ++#endif /* BCMPKTPOOL */ ++ ++#ifndef PKTPOOL_LEN_MAX ++#define PKTPOOL_LEN_MAX 40 ++#endif /* PKTPOOL_LEN_MAX */ ++#define PKTPOOL_CB_MAX 3 ++ ++struct pktpool; ++typedef void (*pktpool_cb_t)(struct pktpool *pool, void *arg); ++typedef struct { ++ pktpool_cb_t cb; ++ void *arg; ++} pktpool_cbinfo_t; ++ ++#ifdef BCMDBG_POOL ++/* pkt pool debug states */ ++#define POOL_IDLE 0 ++#define POOL_RXFILL 1 ++#define POOL_RXDH 2 ++#define POOL_RXD11 3 ++#define POOL_TXDH 4 ++#define POOL_TXD11 5 ++#define POOL_AMPDU 6 ++#define POOL_TXENQ 7 ++ ++typedef struct { ++ void *p; ++ uint32 cycles; ++ uint32 dur; ++} pktpool_dbg_t; ++ ++typedef struct { ++ uint8 txdh; /* tx to host */ ++ uint8 txd11; /* tx to d11 */ ++ uint8 enq; /* waiting in q */ ++ uint8 rxdh; /* rx from host */ ++ uint8 rxd11; /* rx from d11 */ ++ uint8 rxfill; /* dma_rxfill */ ++ uint8 idle; /* avail in pool */ ++} pktpool_stats_t; ++#endif /* BCMDBG_POOL */ ++ ++typedef struct pktpool { ++ bool inited; ++ uint16 r; ++ uint16 w; ++ uint16 len; ++ uint16 maxlen; ++ uint16 plen; ++ bool istx; ++ bool empty; ++ uint8 cbtoggle; ++ uint8 cbcnt; ++ uint8 ecbcnt; ++ bool emptycb_disable; ++ pktpool_cbinfo_t *availcb_excl; ++ pktpool_cbinfo_t cbs[PKTPOOL_CB_MAX]; ++ pktpool_cbinfo_t ecbs[PKTPOOL_CB_MAX]; ++ void *q[PKTPOOL_LEN_MAX + 1]; ++ ++#ifdef BCMDBG_POOL ++ uint8 dbg_cbcnt; ++ pktpool_cbinfo_t dbg_cbs[PKTPOOL_CB_MAX]; ++ uint16 dbg_qlen; ++ pktpool_dbg_t dbg_q[PKTPOOL_LEN_MAX + 1]; ++#endif ++} pktpool_t; ++ ++#if defined(BCM4329C0) ++extern pktpool_t *pktpool_shared_ptr; ++#else ++extern pktpool_t *pktpool_shared; ++#endif /* BCM4329C0 */ ++ ++extern int pktpool_init(osl_t *osh, pktpool_t *pktp, int *pktplen, int plen, bool istx); ++extern int pktpool_deinit(osl_t *osh, pktpool_t *pktp); ++extern int pktpool_fill(osl_t *osh, pktpool_t *pktp, bool minimal); ++extern void* pktpool_get(pktpool_t *pktp); ++extern void pktpool_free(pktpool_t *pktp, void *p); ++extern int pktpool_add(pktpool_t *pktp, void *p); ++extern uint16 pktpool_avail(pktpool_t *pktp); ++extern int pktpool_avail_notify_normal(osl_t *osh, pktpool_t *pktp); ++extern int pktpool_avail_notify_exclusive(osl_t *osh, pktpool_t *pktp, pktpool_cb_t cb); ++extern int pktpool_avail_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg); ++extern int pktpool_empty_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg); ++extern int pktpool_setmaxlen(pktpool_t *pktp, uint16 maxlen); ++extern int pktpool_setmaxlen_strict(osl_t *osh, pktpool_t *pktp, uint16 maxlen); ++extern void pktpool_emptycb_disable(pktpool_t *pktp, bool disable); ++extern bool pktpool_emptycb_disabled(pktpool_t *pktp); ++ ++#define POOLPTR(pp) ((pktpool_t *)(pp)) ++#define pktpool_len(pp) (POOLPTR(pp)->len - 1) ++#define pktpool_plen(pp) (POOLPTR(pp)->plen) ++#define pktpool_maxlen(pp) (POOLPTR(pp)->maxlen) ++ ++#ifdef BCMDBG_POOL ++extern int pktpool_dbg_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg); ++extern int pktpool_start_trigger(pktpool_t *pktp, void *p); ++extern int pktpool_dbg_dump(pktpool_t *pktp); ++extern int pktpool_dbg_notify(pktpool_t *pktp); ++extern int pktpool_stats_dump(pktpool_t *pktp, pktpool_stats_t *stats); ++#endif /* BCMDBG_POOL */ ++ ++/* forward definition of ether_addr structure used by some function prototypes */ ++ ++struct ether_addr; ++ ++extern int ether_isbcast(const void *ea); ++extern int ether_isnulladdr(const void *ea); ++ ++/* operations on a specific precedence in packet queue */ ++ ++#define pktq_psetmax(pq, prec, _max) ((pq)->q[prec].max = (_max)) ++#define pktq_pmax(pq, prec) ((pq)->q[prec].max) ++#define pktq_plen(pq, prec) ((pq)->q[prec].len) ++#define pktq_pavail(pq, prec) ((pq)->q[prec].max - (pq)->q[prec].len) ++#define pktq_pfull(pq, prec) ((pq)->q[prec].len >= (pq)->q[prec].max) ++#define pktq_pempty(pq, prec) ((pq)->q[prec].len == 0) ++ ++#define pktq_ppeek(pq, prec) ((pq)->q[prec].head) ++#define pktq_ppeek_tail(pq, prec) ((pq)->q[prec].tail) ++ ++extern void *pktq_penq(struct pktq *pq, int prec, void *p); ++extern void *pktq_penq_head(struct pktq *pq, int prec, void *p); ++extern void *pktq_pdeq(struct pktq *pq, int prec); ++extern void *pktq_pdeq_prev(struct pktq *pq, int prec, void *prev_p); ++extern void *pktq_pdeq_tail(struct pktq *pq, int prec); ++/* Empty the queue at particular precedence level */ ++extern void pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir, ++ ifpkt_cb_t fn, int arg); ++/* Remove a specified packet from its queue */ ++extern bool pktq_pdel(struct pktq *pq, void *p, int prec); ++ ++/* operations on a set of precedences in packet queue */ ++ ++extern int pktq_mlen(struct pktq *pq, uint prec_bmp); ++extern void *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); ++extern void *pktq_mpeek(struct pktq *pq, uint prec_bmp, int *prec_out); ++ ++/* operations on packet queue as a whole */ ++ ++#define pktq_len(pq) ((int)(pq)->len) ++#define pktq_max(pq) ((int)(pq)->max) ++#define pktq_avail(pq) ((int)((pq)->max - (pq)->len)) ++#define pktq_full(pq) ((pq)->len >= (pq)->max) ++#define pktq_empty(pq) ((pq)->len == 0) ++ ++/* operations for single precedence queues */ ++#define pktenq(pq, p) pktq_penq(((struct pktq *)(void *)pq), 0, (p)) ++#define pktenq_head(pq, p) pktq_penq_head(((struct pktq *)(void *)pq), 0, (p)) ++#define pktdeq(pq) pktq_pdeq(((struct pktq *)(void *)pq), 0) ++#define pktdeq_tail(pq) pktq_pdeq_tail(((struct pktq *)(void *)pq), 0) ++#define pktqinit(pq, len) pktq_init(((struct pktq *)(void *)pq), 1, len) ++ ++extern void pktq_init(struct pktq *pq, int num_prec, int max_len); ++extern void pktq_set_max_plen(struct pktq *pq, int prec, int max_len); ++ ++/* prec_out may be NULL if caller is not interested in return value */ ++extern void *pktq_deq(struct pktq *pq, int *prec_out); ++extern void *pktq_deq_tail(struct pktq *pq, int *prec_out); ++extern void *pktq_peek(struct pktq *pq, int *prec_out); ++extern void *pktq_peek_tail(struct pktq *pq, int *prec_out); ++extern void pktq_flush(osl_t *osh, struct pktq *pq, bool dir, ifpkt_cb_t fn, int arg); ++ ++/* externs */ ++/* packet */ ++extern uint pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf); ++extern uint pktfrombuf(osl_t *osh, void *p, uint offset, int len, uchar *buf); ++extern uint pkttotlen(osl_t *osh, void *p); ++extern void *pktlast(osl_t *osh, void *p); ++extern uint pktsegcnt(osl_t *osh, void *p); ++extern uint pktsegcnt_war(osl_t *osh, void *p); ++extern uint8 *pktdataoffset(osl_t *osh, void *p, uint offset); ++extern void *pktoffset(osl_t *osh, void *p, uint offset); ++ ++/* Get priority from a packet and pass it back in scb (or equiv) */ ++#define PKTPRIO_VDSCP 0x100 /* DSCP prio found after VLAN tag */ ++#define PKTPRIO_VLAN 0x200 /* VLAN prio found */ ++#define PKTPRIO_UPD 0x400 /* DSCP used to update VLAN prio */ ++#define PKTPRIO_DSCP 0x800 /* DSCP prio found */ ++ ++extern uint pktsetprio(void *pkt, bool update_vtag); ++ ++/* string */ ++extern int BCMROMFN(bcm_atoi)(const char *s); ++extern ulong BCMROMFN(bcm_strtoul)(const char *cp, char **endp, uint base); ++extern char *BCMROMFN(bcmstrstr)(const char *haystack, const char *needle); ++extern char *BCMROMFN(bcmstrcat)(char *dest, const char *src); ++extern char *BCMROMFN(bcmstrncat)(char *dest, const char *src, uint size); ++extern ulong wchar2ascii(char *abuf, ushort *wbuf, ushort wbuflen, ulong abuflen); ++char* bcmstrtok(char **string, const char *delimiters, char *tokdelim); ++int bcmstricmp(const char *s1, const char *s2); ++int bcmstrnicmp(const char* s1, const char* s2, int cnt); ++ ++ ++/* ethernet address */ ++extern char *bcm_ether_ntoa(const struct ether_addr *ea, char *buf); ++extern int BCMROMFN(bcm_ether_atoe)(const char *p, struct ether_addr *ea); ++ ++/* ip address */ ++struct ipv4_addr; ++extern char *bcm_ip_ntoa(struct ipv4_addr *ia, char *buf); ++ ++/* delay */ ++extern void bcm_mdelay(uint ms); ++/* variable access */ ++#if defined(DONGLEBUILD) && !defined(WLTEST) ++#ifdef BCMDBG ++#define NVRAM_RECLAIM_CHECK(name) \ ++ if (attach_part_reclaimed == TRUE) { \ ++ printf("%s: NVRAM already reclaimed, %s\n", __FUNCTION__, (name)); \ ++ *(char*) 0 = 0; /* TRAP */ \ ++ return NULL; \ ++ } ++#else /* BCMDBG */ ++#define NVRAM_RECLAIM_CHECK(name) \ ++ if (attach_part_reclaimed == TRUE) { \ ++ *(char*) 0 = 0; /* TRAP */ \ ++ return NULL; \ ++ } ++#endif /* BCMDBG */ ++#else /* DONGLEBUILD && !WLTEST && !BCMINTERNAL && !BCMDBG_DUMP */ ++#define NVRAM_RECLAIM_CHECK(name) ++#endif ++ ++extern char *getvar(char *vars, const char *name); ++extern int getintvar(char *vars, const char *name); ++extern int getintvararray(char *vars, const char *name, int index); ++extern int getintvararraysize(char *vars, const char *name); ++extern uint getgpiopin(char *vars, char *pin_name, uint def_pin); ++extern int getwanport(void); ++extern int getbrcmtag(void); ++#ifdef BCMDBG ++extern void prpkt(const char *msg, osl_t *osh, void *p0); ++#endif /* BCMDBG */ ++#ifdef BCMPERFSTATS ++extern void bcm_perf_enable(void); ++extern void bcmstats(char *fmt); ++extern void bcmlog(char *fmt, uint a1, uint a2); ++extern void bcmdumplog(char *buf, int size); ++extern int bcmdumplogent(char *buf, uint idx); ++#else ++#define bcm_perf_enable() ++#define bcmstats(fmt) ++#define bcmlog(fmt, a1, a2) ++#define bcmdumplog(buf, size) *buf = '\0' ++#define bcmdumplogent(buf, idx) -1 ++#endif /* BCMPERFSTATS */ ++ ++#if defined(BCMTSTAMPEDLOGS) ++#define TSF_TICKS_PER_MS 1024 ++/* Store a TSF timestamp and a log line in the log buffer */ ++extern void bcmtslog(uint32 tstamp, char *fmt, uint a1, uint a2); ++/* Print out the log buffer with timestamps */ ++extern void bcmprinttslogs(void); ++/* Print out a microsecond timestamp as "sec.ms.us " */ ++extern void bcmprinttstamp(uint32 us); ++/* Dump to buffer a microsecond timestamp as "sec.ms.us " */ ++extern void bcmdumptslog(char *buf, int size); ++#else ++#define bcmtslog(tstamp, fmt, a1, a2) ++#define bcmprinttslogs() ++#define bcmprinttstamp(us) ++#define bcmdumptslog(buf, size) ++#endif /* BCMTSTAMPEDLOGS */ ++ ++extern char *bcm_nvram_vars(uint *length); ++extern int bcm_nvram_cache(void *sih); ++ ++/* Support for sharing code across in-driver iovar implementations. ++ * The intent is that a driver use this structure to map iovar names ++ * to its (private) iovar identifiers, and the lookup function to ++ * find the entry. Macros are provided to map ids and get/set actions ++ * into a single number space for a switch statement. ++ */ ++ ++/* iovar structure */ ++typedef struct bcm_iovar { ++ const char *name; /* name for lookup and display */ ++ uint16 varid; /* id for switch */ ++ uint16 flags; /* driver-specific flag bits */ ++ uint16 type; /* base type of argument */ ++ uint16 minlen; /* min length for buffer vars */ ++} bcm_iovar_t; ++ ++/* varid definitions are per-driver, may use these get/set bits */ ++ ++/* IOVar action bits for id mapping */ ++#define IOV_GET 0 /* Get an iovar */ ++#define IOV_SET 1 /* Set an iovar */ ++ ++/* Varid to actionid mapping */ ++#define IOV_GVAL(id) ((id) * 2) ++#define IOV_SVAL(id) ((id) * 2 + IOV_SET) ++#define IOV_ISSET(actionid) ((actionid & IOV_SET) == IOV_SET) ++#define IOV_ID(actionid) (actionid >> 1) ++ ++/* flags are per-driver based on driver attributes */ ++ ++extern const bcm_iovar_t *bcm_iovar_lookup(const bcm_iovar_t *table, const char *name); ++extern int bcm_iovar_lencheck(const bcm_iovar_t *table, void *arg, int len, bool set); ++#if defined(WLTINYDUMP) || defined(BCMDBG) || defined(WLMSG_INFORM) || \ ++ defined(WLMSG_ASSOC) || defined(WLMSG_PRPKT) || defined(WLMSG_WSEC) ++extern int bcm_format_ssid(char* buf, const uchar ssid[], uint ssid_len); ++#endif /* WLTINYDUMP || BCMDBG || WLMSG_INFORM || WLMSG_ASSOC || WLMSG_PRPKT */ ++#endif /* BCMDRIVER */ ++ ++/* Base type definitions */ ++#define IOVT_VOID 0 /* no value (implictly set only) */ ++#define IOVT_BOOL 1 /* any value ok (zero/nonzero) */ ++#define IOVT_INT8 2 /* integer values are range-checked */ ++#define IOVT_UINT8 3 /* unsigned int 8 bits */ ++#define IOVT_INT16 4 /* int 16 bits */ ++#define IOVT_UINT16 5 /* unsigned int 16 bits */ ++#define IOVT_INT32 6 /* int 32 bits */ ++#define IOVT_UINT32 7 /* unsigned int 32 bits */ ++#define IOVT_BUFFER 8 /* buffer is size-checked as per minlen */ ++#define BCM_IOVT_VALID(type) (((unsigned int)(type)) <= IOVT_BUFFER) ++ ++/* Initializer for IOV type strings */ ++#define BCM_IOV_TYPE_INIT { \ ++ "void", \ ++ "bool", \ ++ "int8", \ ++ "uint8", \ ++ "int16", \ ++ "uint16", \ ++ "int32", \ ++ "uint32", \ ++ "buffer", \ ++ "" } ++ ++#define BCM_IOVT_IS_INT(type) (\ ++ (type == IOVT_BOOL) || \ ++ (type == IOVT_INT8) || \ ++ (type == IOVT_UINT8) || \ ++ (type == IOVT_INT16) || \ ++ (type == IOVT_UINT16) || \ ++ (type == IOVT_INT32) || \ ++ (type == IOVT_UINT32)) ++ ++/* ** driver/apps-shared section ** */ ++ ++#define BCME_STRLEN 64 /* Max string length for BCM errors */ ++#define VALID_BCMERROR(e) ((e <= 0) && (e >= BCME_LAST)) ++ ++ ++/* ++ * error codes could be added but the defined ones shouldn't be changed/deleted ++ * these error codes are exposed to the user code ++ * when ever a new error code is added to this list ++ * please update errorstring table with the related error string and ++ * update osl files with os specific errorcode map ++*/ ++ ++#define BCME_OK 0 /* Success */ ++#define BCME_ERROR -1 /* Error generic */ ++#define BCME_BADARG -2 /* Bad Argument */ ++#define BCME_BADOPTION -3 /* Bad option */ ++#define BCME_NOTUP -4 /* Not up */ ++#define BCME_NOTDOWN -5 /* Not down */ ++#define BCME_NOTAP -6 /* Not AP */ ++#define BCME_NOTSTA -7 /* Not STA */ ++#define BCME_BADKEYIDX -8 /* BAD Key Index */ ++#define BCME_RADIOOFF -9 /* Radio Off */ ++#define BCME_NOTBANDLOCKED -10 /* Not band locked */ ++#define BCME_NOCLK -11 /* No Clock */ ++#define BCME_BADRATESET -12 /* BAD Rate valueset */ ++#define BCME_BADBAND -13 /* BAD Band */ ++#define BCME_BUFTOOSHORT -14 /* Buffer too short */ ++#define BCME_BUFTOOLONG -15 /* Buffer too long */ ++#define BCME_BUSY -16 /* Busy */ ++#define BCME_NOTASSOCIATED -17 /* Not Associated */ ++#define BCME_BADSSIDLEN -18 /* Bad SSID len */ ++#define BCME_OUTOFRANGECHAN -19 /* Out of Range Channel */ ++#define BCME_BADCHAN -20 /* Bad Channel */ ++#define BCME_BADADDR -21 /* Bad Address */ ++#define BCME_NORESOURCE -22 /* Not Enough Resources */ ++#define BCME_UNSUPPORTED -23 /* Unsupported */ ++#define BCME_BADLEN -24 /* Bad length */ ++#define BCME_NOTREADY -25 /* Not Ready */ ++#define BCME_EPERM -26 /* Not Permitted */ ++#define BCME_NOMEM -27 /* No Memory */ ++#define BCME_ASSOCIATED -28 /* Associated */ ++#define BCME_RANGE -29 /* Not In Range */ ++#define BCME_NOTFOUND -30 /* Not Found */ ++#define BCME_WME_NOT_ENABLED -31 /* WME Not Enabled */ ++#define BCME_TSPEC_NOTFOUND -32 /* TSPEC Not Found */ ++#define BCME_ACM_NOTSUPPORTED -33 /* ACM Not Supported */ ++#define BCME_NOT_WME_ASSOCIATION -34 /* Not WME Association */ ++#define BCME_SDIO_ERROR -35 /* SDIO Bus Error */ ++#define BCME_DONGLE_DOWN -36 /* Dongle Not Accessible */ ++#define BCME_VERSION -37 /* Incorrect version */ ++#define BCME_TXFAIL -38 /* TX failure */ ++#define BCME_RXFAIL -39 /* RX failure */ ++#define BCME_NODEVICE -40 /* Device not present */ ++#define BCME_NMODE_DISABLED -41 /* NMODE disabled */ ++#define BCME_NONRESIDENT -42 /* access to nonresident overlay */ ++#define BCME_LAST BCME_NONRESIDENT ++ ++/* These are collection of BCME Error strings */ ++#define BCMERRSTRINGTABLE { \ ++ "OK", \ ++ "Undefined error", \ ++ "Bad Argument", \ ++ "Bad Option", \ ++ "Not up", \ ++ "Not down", \ ++ "Not AP", \ ++ "Not STA", \ ++ "Bad Key Index", \ ++ "Radio Off", \ ++ "Not band locked", \ ++ "No clock", \ ++ "Bad Rate valueset", \ ++ "Bad Band", \ ++ "Buffer too short", \ ++ "Buffer too long", \ ++ "Busy", \ ++ "Not Associated", \ ++ "Bad SSID len", \ ++ "Out of Range Channel", \ ++ "Bad Channel", \ ++ "Bad Address", \ ++ "Not Enough Resources", \ ++ "Unsupported", \ ++ "Bad length", \ ++ "Not Ready", \ ++ "Not Permitted", \ ++ "No Memory", \ ++ "Associated", \ ++ "Not In Range", \ ++ "Not Found", \ ++ "WME Not Enabled", \ ++ "TSPEC Not Found", \ ++ "ACM Not Supported", \ ++ "Not WME Association", \ ++ "SDIO Bus Error", \ ++ "Dongle Not Accessible", \ ++ "Incorrect version", \ ++ "TX Failure", \ ++ "RX Failure", \ ++ "Device Not Present", \ ++ "NMODE Disabled", \ ++ "Nonresident overlay access", \ ++} ++ ++#ifndef ABS ++#define ABS(a) (((a) < 0) ? -(a) : (a)) ++#endif /* ABS */ ++ ++#ifndef MIN ++#define MIN(a, b) (((a) < (b)) ? (a) : (b)) ++#endif /* MIN */ ++ ++#ifndef MAX ++#define MAX(a, b) (((a) > (b)) ? (a) : (b)) ++#endif /* MAX */ ++ ++#define CEIL(x, y) (((x) + ((y) - 1)) / (y)) ++#define ROUNDUP(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) ++#define ISALIGNED(a, x) (((uintptr)(a) & ((x) - 1)) == 0) ++#define ALIGN_ADDR(addr, boundary) (void *)(((uintptr)(addr) + (boundary) - 1) \ ++ & ~((boundary) - 1)) ++#define ALIGN_SIZE(size, boundary) (((size) + (boundary) - 1) \ ++ & ~((boundary) - 1)) ++#define ISPOWEROF2(x) ((((x) - 1) & (x)) == 0) ++#define VALID_MASK(mask) !((mask) & ((mask) + 1)) ++ ++#ifndef OFFSETOF ++#ifdef __ARMCC_VERSION ++/* ++ * The ARM RVCT compiler complains when using OFFSETOF where a constant ++ * expression is expected, such as an initializer for a static object. ++ * offsetof from the runtime library doesn't have that problem. ++ */ ++#include ++#define OFFSETOF(type, member) offsetof(type, member) ++#else ++#define OFFSETOF(type, member) ((uint)(uintptr)&((type *)0)->member) ++#endif /* __ARMCC_VERSION */ ++#endif /* OFFSETOF */ ++ ++#ifndef ARRAYSIZE ++#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0])) ++#endif ++ ++/* Reference a function; used to prevent a static function from being optimized out */ ++extern void *_bcmutils_dummy_fn; ++#define REFERENCE_FUNCTION(f) (_bcmutils_dummy_fn = (void *)(f)) ++ ++/* bit map related macros */ ++#ifndef setbit ++#ifndef NBBY /* the BSD family defines NBBY */ ++#define NBBY 8 /* 8 bits per byte */ ++#endif /* #ifndef NBBY */ ++#define setbit(a, i) (((uint8 *)a)[(i) / NBBY] |= 1 << ((i) % NBBY)) ++#define clrbit(a, i) (((uint8 *)a)[(i) / NBBY] &= ~(1 << ((i) % NBBY))) ++#define isset(a, i) (((const uint8 *)a)[(i) / NBBY] & (1 << ((i) % NBBY))) ++#define isclr(a, i) ((((const uint8 *)a)[(i) / NBBY] & (1 << ((i) % NBBY))) == 0) ++#endif /* setbit */ ++ ++#define NBITS(type) (sizeof(type) * 8) ++#define NBITVAL(nbits) (1 << (nbits)) ++#define MAXBITVAL(nbits) ((1 << (nbits)) - 1) ++#define NBITMASK(nbits) MAXBITVAL(nbits) ++#define MAXNBVAL(nbyte) MAXBITVAL((nbyte) * 8) ++ ++/* basic mux operation - can be optimized on several architectures */ ++#define MUX(pred, true, false) ((pred) ? (true) : (false)) ++ ++/* modulo inc/dec - assumes x E [0, bound - 1] */ ++#define MODDEC(x, bound) MUX((x) == 0, (bound) - 1, (x) - 1) ++#define MODINC(x, bound) MUX((x) == (bound) - 1, 0, (x) + 1) ++ ++/* modulo inc/dec, bound = 2^k */ ++#define MODDEC_POW2(x, bound) (((x) - 1) & ((bound) - 1)) ++#define MODINC_POW2(x, bound) (((x) + 1) & ((bound) - 1)) ++ ++/* modulo add/sub - assumes x, y E [0, bound - 1] */ ++#define MODADD(x, y, bound) \ ++ MUX((x) + (y) >= (bound), (x) + (y) - (bound), (x) + (y)) ++#define MODSUB(x, y, bound) \ ++ MUX(((int)(x)) - ((int)(y)) < 0, (x) - (y) + (bound), (x) - (y)) ++ ++/* module add/sub, bound = 2^k */ ++#define MODADD_POW2(x, y, bound) (((x) + (y)) & ((bound) - 1)) ++#define MODSUB_POW2(x, y, bound) (((x) - (y)) & ((bound) - 1)) ++ ++/* crc defines */ ++#define CRC8_INIT_VALUE 0xff /* Initial CRC8 checksum value */ ++#define CRC8_GOOD_VALUE 0x9f /* Good final CRC8 checksum value */ ++#define CRC16_INIT_VALUE 0xffff /* Initial CRC16 checksum value */ ++#define CRC16_GOOD_VALUE 0xf0b8 /* Good final CRC16 checksum value */ ++#define CRC32_INIT_VALUE 0xffffffff /* Initial CRC32 checksum value */ ++#define CRC32_GOOD_VALUE 0xdebb20e3 /* Good final CRC32 checksum value */ ++ ++/* use for direct output of MAC address in printf etc */ ++#define MACF "%02x:%02x:%02x:%02x:%02x:%02x" ++#define ETHERP_TO_MACF(ea) ((struct ether_addr *) (ea))->octet[0], \ ++ ((struct ether_addr *) (ea))->octet[1], \ ++ ((struct ether_addr *) (ea))->octet[2], \ ++ ((struct ether_addr *) (ea))->octet[3], \ ++ ((struct ether_addr *) (ea))->octet[4], \ ++ ((struct ether_addr *) (ea))->octet[5] ++ ++#define ETHER_TO_MACF(ea) (ea).octet[0], \ ++ (ea).octet[1], \ ++ (ea).octet[2], \ ++ (ea).octet[3], \ ++ (ea).octet[4], \ ++ (ea).octet[5] ++ ++/* bcm_format_flags() bit description structure */ ++typedef struct bcm_bit_desc { ++ uint32 bit; ++ const char* name; ++} bcm_bit_desc_t; ++ ++/* tag_ID/length/value_buffer tuple */ ++typedef struct bcm_tlv { ++ uint8 id; ++ uint8 len; ++ uint8 data[1]; ++} bcm_tlv_t; ++ ++/* Check that bcm_tlv_t fits into the given buflen */ ++#define bcm_valid_tlv(elt, buflen) ((buflen) >= 2 && (int)(buflen) >= (int)(2 + (elt)->len)) ++ ++/* buffer length for ethernet address from bcm_ether_ntoa() */ ++#define ETHER_ADDR_STR_LEN 18 /* 18-bytes of Ethernet address buffer length */ ++ ++/* crypto utility function */ ++/* 128-bit xor: *dst = *src1 xor *src2. dst1, src1 and src2 may have any alignment */ ++static INLINE void ++xor_128bit_block(const uint8 *src1, const uint8 *src2, uint8 *dst) ++{ ++ if ( ++#ifdef __i386__ ++ 1 || ++#endif ++ (((uintptr)src1 | (uintptr)src2 | (uintptr)dst) & 3) == 0) { ++ /* ARM CM3 rel time: 1229 (727 if alignment check could be omitted) */ ++ /* x86 supports unaligned. This version runs 6x-9x faster on x86. */ ++ ((uint32 *)dst)[0] = ((const uint32 *)src1)[0] ^ ((const uint32 *)src2)[0]; ++ ((uint32 *)dst)[1] = ((const uint32 *)src1)[1] ^ ((const uint32 *)src2)[1]; ++ ((uint32 *)dst)[2] = ((const uint32 *)src1)[2] ^ ((const uint32 *)src2)[2]; ++ ((uint32 *)dst)[3] = ((const uint32 *)src1)[3] ^ ((const uint32 *)src2)[3]; ++ } else { ++ /* ARM CM3 rel time: 4668 (4191 if alignment check could be omitted) */ ++ int k; ++ for (k = 0; k < 16; k++) ++ dst[k] = src1[k] ^ src2[k]; ++ } ++} ++ ++/* externs */ ++/* crc */ ++extern uint8 BCMROMFN(hndcrc8)(uint8 *p, uint nbytes, uint8 crc); ++extern uint16 BCMROMFN(hndcrc16)(uint8 *p, uint nbytes, uint16 crc); ++extern uint32 BCMROMFN(hndcrc32)(uint8 *p, uint nbytes, uint32 crc); ++ ++/* format/print */ ++#if defined(BCMDBG) || defined(DHD_DEBUG) || defined(BCMDBG_ERR) || \ ++ defined(WLMSG_PRHDRS) || defined(WLMSG_PRPKT) || defined(WLMSG_ASSOC) ++extern int bcm_format_flags(const bcm_bit_desc_t *bd, uint32 flags, char* buf, int len); ++#endif ++ ++#if defined(BCMDBG) || defined(DHD_DEBUG) || defined(BCMDBG_ERR) || \ ++ defined(WLMSG_PRHDRS) || defined(WLMSG_PRPKT) || defined(WLMSG_ASSOC) || \ ++ defined(WLMEDIA_PEAKRATE) ++extern int bcm_format_hex(char *str, const void *bytes, int len); ++#endif ++ ++#ifdef BCMDBG ++extern void deadbeef(void *p, size_t len); ++#endif ++extern const char *bcm_crypto_algo_name(uint algo); ++extern char *bcm_chipname(uint chipid, char *buf, uint len); ++extern char *bcm_brev_str(uint32 brev, char *buf); ++extern void printbig(char *buf); ++extern void prhex(const char *msg, uchar *buf, uint len); ++ ++/* IE parsing */ ++extern bcm_tlv_t *BCMROMFN(bcm_next_tlv)(bcm_tlv_t *elt, int *buflen); ++extern bcm_tlv_t *BCMROMFN(bcm_parse_tlvs)(void *buf, int buflen, uint key); ++extern bcm_tlv_t *BCMROMFN(bcm_parse_ordered_tlvs)(void *buf, int buflen, uint key); ++ ++/* bcmerror */ ++extern const char *bcmerrorstr(int bcmerror); ++extern bcm_tlv_t *BCMROMFN(bcm_parse_tlvs)(void *buf, int buflen, uint key); ++ ++/* multi-bool data type: set of bools, mbool is true if any is set */ ++typedef uint32 mbool; ++#define mboolset(mb, bit) ((mb) |= (bit)) /* set one bool */ ++#define mboolclr(mb, bit) ((mb) &= ~(bit)) /* clear one bool */ ++#define mboolisset(mb, bit) (((mb) & (bit)) != 0) /* TRUE if one bool is set */ ++#define mboolmaskset(mb, mask, val) ((mb) = (((mb) & ~(mask)) | (val))) ++ ++/* generic datastruct to help dump routines */ ++struct fielddesc { ++ const char *nameandfmt; ++ uint32 offset; ++ uint32 len; ++}; ++ ++extern void bcm_binit(struct bcmstrbuf *b, char *buf, uint size); ++extern void bcm_bprhex(struct bcmstrbuf *b, const char *msg, bool newline, uint8 *buf, int len); ++ ++extern void bcm_inc_bytes(uchar *num, int num_bytes, uint8 amount); ++extern int bcm_cmp_bytes(const uchar *arg1, const uchar *arg2, uint8 nbytes); ++extern void bcm_print_bytes(const char *name, const uchar *cdata, int len); ++ ++typedef uint32 (*bcmutl_rdreg_rtn)(void *arg0, uint arg1, uint32 offset); ++extern uint bcmdumpfields(bcmutl_rdreg_rtn func_ptr, void *arg0, uint arg1, struct fielddesc *str, ++ char *buf, uint32 bufsize); ++extern uint BCMROMFN(bcm_bitcount)(uint8 *bitmap, uint bytelength); ++ ++extern int bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...); ++ ++/* power conversion */ ++extern uint16 BCMROMFN(bcm_qdbm_to_mw)(uint8 qdbm); ++extern uint8 BCMROMFN(bcm_mw_to_qdbm)(uint16 mw); ++ ++extern int32 exthdr_validate(char *ptr, uint size); ++extern uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint len); ++ ++unsigned int process_nvram_vars(char *varbuf, unsigned int len); ++ ++#ifdef __cplusplus ++ } ++#endif ++ ++#endif /* _bcmutils_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmwifi.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmwifi.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmwifi.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmwifi.h 2017-11-09 17:53:43.942304000 +0800 +@@ -0,0 +1,456 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Misc utility routines for WL and Apps ++ * This header file housing the define and function prototype use by ++ * both the wl driver, tools & Apps. ++ * ++ * $Id: bcmwifi.h 293848 2011-11-03 12:31:04Z $ ++ */ ++ ++#ifndef _bcmwifi_h_ ++#define _bcmwifi_h_ ++ ++ ++/* A chanspec holds the channel number, band, bandwidth and control sideband */ ++typedef uint16 chanspec_t; ++ ++/* channel defines */ ++#define CH_UPPER_SB 0x01 ++#define CH_LOWER_SB 0x02 ++#define CH_EWA_VALID 0x04 ++#define CH_80MHZ_APART 16 ++#define CH_40MHZ_APART 8 ++#define CH_20MHZ_APART 4 ++#define CH_10MHZ_APART 2 ++#define CH_5MHZ_APART 1 /* 2G band channels are 5 Mhz apart */ ++#define CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */ ++#define MAXCHANNEL 224 /* max # supported channels. The max channel no is 216, ++ * this is that + 1 rounded up to a multiple of NBBY (8). ++ * DO NOT MAKE it > 255: channels are uint8's all over ++ */ ++#define CHSPEC_CTLOVLP(sp1, sp2, sep) ABS(wf_chspec_ctlchan(sp1) - wf_chspec_ctlchan(sp2)) < (sep) ++ ++#ifndef D11AC_IOTYPES ++ ++#define WL_CHANSPEC_CHAN_MASK 0x00ff ++#define WL_CHANSPEC_CHAN_SHIFT 0 ++ ++#define WL_CHANSPEC_CTL_SB_MASK 0x0300 ++#define WL_CHANSPEC_CTL_SB_SHIFT 8 ++#define WL_CHANSPEC_CTL_SB_LOWER 0x0100 ++#define WL_CHANSPEC_CTL_SB_UPPER 0x0200 ++#define WL_CHANSPEC_CTL_SB_NONE 0x0300 ++ ++#define WL_CHANSPEC_BW_MASK 0x0C00 ++#define WL_CHANSPEC_BW_SHIFT 10 ++#define WL_CHANSPEC_BW_10 0x0400 ++#define WL_CHANSPEC_BW_20 0x0800 ++#define WL_CHANSPEC_BW_40 0x0C00 ++ ++#define WL_CHANSPEC_BAND_MASK 0xf000 ++#define WL_CHANSPEC_BAND_SHIFT 12 ++#define WL_CHANSPEC_BAND_5G 0x1000 ++#define WL_CHANSPEC_BAND_2G 0x2000 ++#define INVCHANSPEC 255 ++ ++/* channel defines */ ++#define LOWER_20_SB(channel) (((channel) > CH_10MHZ_APART) ? ((channel) - CH_10MHZ_APART) : 0) ++#define UPPER_20_SB(channel) (((channel) < (MAXCHANNEL - CH_10MHZ_APART)) ? \ ++ ((channel) + CH_10MHZ_APART) : 0) ++#define CHSPEC_WLCBANDUNIT(chspec) (CHSPEC_IS5G(chspec) ? BAND_5G_INDEX : BAND_2G_INDEX) ++#define CH20MHZ_CHSPEC(channel) (chanspec_t)((chanspec_t)(channel) | WL_CHANSPEC_BW_20 | \ ++ WL_CHANSPEC_CTL_SB_NONE | (((channel) <= CH_MAX_2G_CHANNEL) ? \ ++ WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G)) ++#define NEXT_20MHZ_CHAN(channel) (((channel) < (MAXCHANNEL - CH_20MHZ_APART)) ? \ ++ ((channel) + CH_20MHZ_APART) : 0) ++#define CH40MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \ ++ ((channel) | (ctlsb) | WL_CHANSPEC_BW_40 | \ ++ ((channel) <= CH_MAX_2G_CHANNEL ? WL_CHANSPEC_BAND_2G : \ ++ WL_CHANSPEC_BAND_5G)) ++#define CHSPEC_CHANNEL(chspec) ((uint8)((chspec) & WL_CHANSPEC_CHAN_MASK)) ++#define CHSPEC_BAND(chspec) ((chspec) & WL_CHANSPEC_BAND_MASK) ++ ++/* chanspec stores radio channel & flags to indicate control channel location, i.e. upper/lower */ ++#define CHSPEC_CTL_SB(chspec) ((chspec) & WL_CHANSPEC_CTL_SB_MASK) ++#define CHSPEC_BW(chspec) ((chspec) & WL_CHANSPEC_BW_MASK) ++ ++#ifdef WL11N_20MHZONLY ++ ++#define CHSPEC_IS10(chspec) 0 ++#define CHSPEC_IS20(chspec) 1 ++#ifndef CHSPEC_IS40 ++#define CHSPEC_IS40(chspec) 0 ++#endif ++ ++#else /* !WL11N_20MHZONLY */ ++ ++#define CHSPEC_IS10(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_10) ++#define CHSPEC_IS20(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20) ++#ifndef CHSPEC_IS40 ++#define CHSPEC_IS40(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40) ++#endif ++ ++#endif /* !WL11N_20MHZONLY */ ++ ++#define CHSPEC_IS5G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G) ++#define CHSPEC_IS2G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_2G) ++#define CHSPEC_SB_NONE(chspec) (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_NONE) ++#define CHSPEC_SB_UPPER(chspec) (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_UPPER) ++#define CHSPEC_SB_LOWER(chspec) (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_LOWER) ++#define CHSPEC_CTL_CHAN(chspec) ((CHSPEC_SB_LOWER(chspec)) ? \ ++ (LOWER_20_SB(((chspec) & WL_CHANSPEC_CHAN_MASK))) : \ ++ (UPPER_20_SB(((chspec) & WL_CHANSPEC_CHAN_MASK)))) ++#define CHSPEC2WLC_BAND(chspec) (CHSPEC_IS5G(chspec) ? WLC_BAND_5G : WLC_BAND_2G) ++ ++#define CHANSPEC_STR_LEN 8 ++ ++#else /* D11AC_IOTYPES */ ++ ++#define WL_CHANSPEC_CHAN_MASK 0x00ff ++#define WL_CHANSPEC_CHAN_SHIFT 0 ++#define WL_CHANSPEC_CHAN1_MASK 0x000f ++#define WL_CHANSPEC_CHAN1_SHIFT 0 ++#define WL_CHANSPEC_CHAN2_MASK 0x00f0 ++#define WL_CHANSPEC_CHAN2_SHIFT 4 ++ ++#define WL_CHANSPEC_CTL_SB_MASK 0x0700 ++#define WL_CHANSPEC_CTL_SB_SHIFT 8 ++#define WL_CHANSPEC_CTL_SB_LLL 0x0000 ++#define WL_CHANSPEC_CTL_SB_LLU 0x0100 ++#define WL_CHANSPEC_CTL_SB_LUL 0x0200 ++#define WL_CHANSPEC_CTL_SB_LUU 0x0300 ++#define WL_CHANSPEC_CTL_SB_ULL 0x0400 ++#define WL_CHANSPEC_CTL_SB_ULU 0x0500 ++#define WL_CHANSPEC_CTL_SB_UUL 0x0600 ++#define WL_CHANSPEC_CTL_SB_UUU 0x0700 ++#define WL_CHANSPEC_CTL_SB_LL WL_CHANSPEC_CTL_SB_LLL ++#define WL_CHANSPEC_CTL_SB_LU WL_CHANSPEC_CTL_SB_LLU ++#define WL_CHANSPEC_CTL_SB_UL WL_CHANSPEC_CTL_SB_LUL ++#define WL_CHANSPEC_CTL_SB_UU WL_CHANSPEC_CTL_SB_LUU ++#define WL_CHANSPEC_CTL_SB_L WL_CHANSPEC_CTL_SB_LLL ++#define WL_CHANSPEC_CTL_SB_U WL_CHANSPEC_CTL_SB_LLU ++#define WL_CHANSPEC_CTL_SB_LOWER WL_CHANSPEC_CTL_SB_LLL ++#define WL_CHANSPEC_CTL_SB_UPPER WL_CHANSPEC_CTL_SB_LLU ++ ++#define WL_CHANSPEC_BW_MASK 0x3800 ++#define WL_CHANSPEC_BW_SHIFT 11 ++#define WL_CHANSPEC_BW_5 0x0000 ++#define WL_CHANSPEC_BW_10 0x0800 ++#define WL_CHANSPEC_BW_20 0x1000 ++#define WL_CHANSPEC_BW_40 0x1800 ++#define WL_CHANSPEC_BW_80 0x2000 ++#define WL_CHANSPEC_BW_160 0x2800 ++#define WL_CHANSPEC_BW_8080 0x3000 ++ ++#define WL_CHANSPEC_BAND_MASK 0xc000 ++#define WL_CHANSPEC_BAND_SHIFT 14 ++#define WL_CHANSPEC_BAND_2G 0x0000 ++#define WL_CHANSPEC_BAND_3G 0x4000 ++#define WL_CHANSPEC_BAND_4G 0x8000 ++#define WL_CHANSPEC_BAND_5G 0xc000 ++#define INVCHANSPEC 255 ++ ++/* channel defines */ ++#define LOWER_20_SB(channel) (((channel) > CH_10MHZ_APART) ? \ ++ ((channel) - CH_10MHZ_APART) : 0) ++#define UPPER_20_SB(channel) (((channel) < (MAXCHANNEL - CH_10MHZ_APART)) ? \ ++ ((channel) + CH_10MHZ_APART) : 0) ++#define CHSPEC_WLCBANDUNIT(chspec) (CHSPEC_IS5G(chspec) ? BAND_5G_INDEX : BAND_2G_INDEX) ++#define CH20MHZ_CHSPEC(channel) (chanspec_t)((chanspec_t)(channel) | WL_CHANSPEC_BW_20 | \ ++ (((channel) <= CH_MAX_2G_CHANNEL) ? \ ++ WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G)) ++#define NEXT_20MHZ_CHAN(channel) (((channel) < (MAXCHANNEL - CH_20MHZ_APART)) ? \ ++ ((channel) + CH_20MHZ_APART) : 0) ++#define CH40MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \ ++ ((channel) | (ctlsb) | WL_CHANSPEC_BW_40 | \ ++ ((channel) <= CH_MAX_2G_CHANNEL ? WL_CHANSPEC_BAND_2G : \ ++ WL_CHANSPEC_BAND_5G)) ++#define CH80MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \ ++ ((channel) | (ctlsb) | WL_CHANSPEC_BW_80 | \ ++ ((channel) <= CH_MAX_2G_CHANNEL ? WL_CHANSPEC_BAND_2G : \ ++ WL_CHANSPEC_BAND_5G)) ++#define CH160MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \ ++ ((channel) | (ctlsb) | WL_CHANSPEC_BW_160 | \ ++ ((channel) <= CH_MAX_2G_CHANNEL ? WL_CHANSPEC_BAND_2G : \ ++ WL_CHANSPEC_BAND_5G)) ++ ++/* simple MACROs to get different fields of chanspec */ ++#define CHSPEC_CHANNEL(chspec) ((uint8)((chspec) & WL_CHANSPEC_CHAN_MASK)) ++#define CHSPEC_CHAN1(chspec) ((chspec) & WL_CHANSPEC_CHAN1_MASK) ++#define CHSPEC_CHAN2(chspec) ((chspec) & WL_CHANSPEC_CHAN2_MASK) ++#define CHSPEC_BAND(chspec) ((chspec) & WL_CHANSPEC_BAND_MASK) ++#define CHSPEC_CTL_SB(chspec) ((chspec) & WL_CHANSPEC_CTL_SB_MASK) ++#define CHSPEC_BW(chspec) ((chspec) & WL_CHANSPEC_BW_MASK) ++ ++#ifdef WL11N_20MHZONLY ++ ++#define CHSPEC_IS10(chspec) 0 ++#define CHSPEC_IS20(chspec) 1 ++#ifndef CHSPEC_IS40 ++#define CHSPEC_IS40(chspec) 0 ++#endif ++#ifndef CHSPEC_IS80 ++#define CHSPEC_IS160(chspec) 0 ++#endif ++#ifndef CHSPEC_IS160 ++#define CHSPEC_IS160(chspec) 0 ++#endif ++#ifndef CHSPEC_IS8080 ++#define CHSPEC_IS8080(chspec) 0 ++#endif ++ ++#else /* !WL11N_20MHZONLY */ ++ ++#define CHSPEC_IS10(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_10) ++#define CHSPEC_IS20(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20) ++#ifndef CHSPEC_IS40 ++#define CHSPEC_IS40(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40) ++#endif ++#ifndef CHSPEC_IS80 ++#define CHSPEC_IS80(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_80) ++#endif ++#ifndef CHSPEC_IS160 ++#define CHSPEC_IS160(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_160) ++#endif ++#ifndef CHSPEC_IS8080 ++#define CHSPEC_IS8080(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_8080) ++#endif ++ ++#endif /* !WL11N_20MHZONLY */ ++ ++#define CHSPEC_IS5G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G) ++#define CHSPEC_IS2G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_2G) ++#define CHSPEC_SB_UPPER(chspec) \ ++ ((((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_UPPER) && \ ++ (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40)) ++#define CHSPEC_SB_LOWER(chspec) \ ++ ((((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_LOWER) && \ ++ (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40)) ++#define CHSPEC2WLC_BAND(chspec) (CHSPEC_IS5G(chspec) ? WLC_BAND_5G : WLC_BAND_2G) ++ ++/** ++ * Number of chars needed for wf_chspec_ntoa() destination character buffer. ++ */ ++#define CHANSPEC_STR_LEN 20 ++ ++ ++/* Legacy Chanspec defines ++ * These are the defines for the previous format of the chanspec_t ++ */ ++#define WL_LCHANSPEC_CHAN_MASK 0x00ff ++#define WL_LCHANSPEC_CHAN_SHIFT 0 ++ ++#define WL_LCHANSPEC_CTL_SB_MASK 0x0300 ++#define WL_LCHANSPEC_CTL_SB_SHIFT 8 ++#define WL_LCHANSPEC_CTL_SB_LOWER 0x0100 ++#define WL_LCHANSPEC_CTL_SB_UPPER 0x0200 ++#define WL_LCHANSPEC_CTL_SB_NONE 0x0300 ++ ++#define WL_LCHANSPEC_BW_MASK 0x0C00 ++#define WL_LCHANSPEC_BW_SHIFT 10 ++#define WL_LCHANSPEC_BW_10 0x0400 ++#define WL_LCHANSPEC_BW_20 0x0800 ++#define WL_LCHANSPEC_BW_40 0x0C00 ++ ++#define WL_LCHANSPEC_BAND_MASK 0xf000 ++#define WL_LCHANSPEC_BAND_SHIFT 12 ++#define WL_LCHANSPEC_BAND_5G 0x1000 ++#define WL_LCHANSPEC_BAND_2G 0x2000 ++ ++#define LCHSPEC_CHANNEL(chspec) ((uint8)((chspec) & WL_LCHANSPEC_CHAN_MASK)) ++#define LCHSPEC_BAND(chspec) ((chspec) & WL_LCHANSPEC_BAND_MASK) ++#define LCHSPEC_CTL_SB(chspec) ((chspec) & WL_LCHANSPEC_CTL_SB_MASK) ++#define LCHSPEC_BW(chspec) ((chspec) & WL_LCHANSPEC_BW_MASK) ++#define LCHSPEC_IS10(chspec) (((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_10) ++#define LCHSPEC_IS20(chspec) (((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_20) ++#define LCHSPEC_IS40(chspec) (((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_40) ++#define LCHSPEC_IS5G(chspec) (((chspec) & WL_LCHANSPEC_BAND_MASK) == WL_LCHANSPEC_BAND_5G) ++#define LCHSPEC_IS2G(chspec) (((chspec) & WL_LCHANSPEC_BAND_MASK) == WL_LCHANSPEC_BAND_2G) ++ ++#define LCHSPEC_CREATE(chan, band, bw, sb) ((uint16)((chan) | (sb) | (bw) | (band))) ++ ++#endif /* D11AC_IOTYPES */ ++ ++/* ++ * WF_CHAN_FACTOR_* constants are used to calculate channel frequency ++ * given a channel number. ++ * chan_freq = chan_factor * 500Mhz + chan_number * 5 ++ */ ++ ++/** ++ * Channel Factor for the starting frequence of 2.4 GHz channels. ++ * The value corresponds to 2407 MHz. ++ */ ++#define WF_CHAN_FACTOR_2_4_G 4814 /* 2.4 GHz band, 2407 MHz */ ++ ++/** ++ * Channel Factor for the starting frequence of 5 GHz channels. ++ * The value corresponds to 5000 MHz. ++ */ ++#define WF_CHAN_FACTOR_5_G 10000 /* 5 GHz band, 5000 MHz */ ++ ++/** ++ * Channel Factor for the starting frequence of 4.9 GHz channels. ++ * The value corresponds to 4000 MHz. ++ */ ++#define WF_CHAN_FACTOR_4_G 8000 /* 4.9 GHz band for Japan */ ++ ++/* defined rate in 500kbps */ ++#define WLC_MAXRATE 108 /* in 500kbps units */ ++#define WLC_RATE_1M 2 /* in 500kbps units */ ++#define WLC_RATE_2M 4 /* in 500kbps units */ ++#define WLC_RATE_5M5 11 /* in 500kbps units */ ++#define WLC_RATE_11M 22 /* in 500kbps units */ ++#define WLC_RATE_6M 12 /* in 500kbps units */ ++#define WLC_RATE_9M 18 /* in 500kbps units */ ++#define WLC_RATE_12M 24 /* in 500kbps units */ ++#define WLC_RATE_18M 36 /* in 500kbps units */ ++#define WLC_RATE_24M 48 /* in 500kbps units */ ++#define WLC_RATE_36M 72 /* in 500kbps units */ ++#define WLC_RATE_48M 96 /* in 500kbps units */ ++#define WLC_RATE_54M 108 /* in 500kbps units */ ++ ++#define WLC_2G_25MHZ_OFFSET 5 /* 2.4GHz band channel offset */ ++ ++/** ++ * Convert chanspec to ascii string ++ * ++ * @param chspec chanspec format ++ * @param buf ascii string of chanspec ++ * ++ * @return pointer to buf with room for at least CHANSPEC_STR_LEN bytes ++ * ++ * @see CHANSPEC_STR_LEN ++ */ ++extern char * wf_chspec_ntoa(chanspec_t chspec, char *buf); ++ ++/** ++ * Convert ascii string to chanspec ++ * ++ * @param a pointer to input string ++ * ++ * @return >= 0 if successful or 0 otherwise ++ */ ++extern chanspec_t wf_chspec_aton(const char *a); ++ ++/** ++ * Verify the chanspec fields are valid. ++ * ++ * Verify the chanspec is using a legal set field values, i.e. that the chanspec ++ * specified a band, bw, ctl_sb and channel and that the combination could be ++ * legal given some set of circumstances. ++ * ++ * @param chanspec input chanspec to verify ++ * ++ * @return TRUE if the chanspec is malformed, FALSE if it looks good. ++ */ ++extern bool wf_chspec_malformed(chanspec_t chanspec); ++ ++/** ++ * Verify the chanspec specifies a valid channel according to 802.11. ++ * ++ * @param chanspec input chanspec to verify ++ * ++ * @return TRUE if the chanspec is a valid 802.11 channel ++ */ ++extern bool wf_chspec_valid(chanspec_t chanspec); ++ ++/** ++ * Return the primary (control) channel. ++ * ++ * This function returns the channel number of the primary 20MHz channel. For ++ * 20MHz channels this is just the channel number. For 40MHz or wider channels ++ * it is the primary 20MHz channel specified by the chanspec. ++ * ++ * @param chspec input chanspec ++ * ++ * @return Returns the channel number of the primary 20MHz channel ++ */ ++extern uint8 wf_chspec_ctlchan(chanspec_t chspec); ++ ++/** ++ * Return the primary (control) chanspec. ++ * ++ * This function returns the chanspec of the primary 20MHz channel. For 20MHz ++ * channels this is just the chanspec. For 40MHz or wider channels it is the ++ * chanspec of the primary 20MHZ channel specified by the chanspec. ++ * ++ * @param chspec input chanspec ++ * ++ * @return Returns the chanspec of the primary 20MHz channel ++ */ ++extern chanspec_t wf_chspec_ctlchspec(chanspec_t chspec); ++ ++/** ++ * Return a channel number corresponding to a frequency. ++ * ++ * Return the channel number for a given frequency and base frequency. ++ * The returned channel number is relative to the given base frequency. ++ * If the given base frequency is zero, a base frequency of 5 GHz is assumed for ++ * frequencies from 5 - 6 GHz, and 2.407 GHz is assumed for 2.4 - 2.5 GHz. ++ * ++ * Frequency is specified in MHz. ++ * The base frequency is specified as (start_factor * 500 kHz). ++ * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G are defined for ++ * 2.4 GHz and 5 GHz bands. ++ * ++ * The returned channel will be in the range [1, 14] in the 2.4 GHz band ++ * and [0, 200] otherwise. ++ * -1 is returned if the start_factor is WF_CHAN_FACTOR_2_4_G and the ++ * frequency is not a 2.4 GHz channel, or if the frequency is not and even ++ * multiple of 5 MHz from the base frequency to the base plus 1 GHz. ++ * ++ * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2 ++ * ++ * @param freq frequency in MHz ++ * @param start_factor base frequency in 500 kHz units, e.g. 10000 for 5 GHz ++ * ++ * @return Returns a channel number ++ * ++ * @see WF_CHAN_FACTOR_2_4_G ++ * @see WF_CHAN_FACTOR_5_G ++ */ ++extern int wf_mhz2channel(uint freq, uint start_factor); ++ ++/** ++ * Return the center frequency in MHz of the given channel and base frequency. ++ * ++ * Return the center frequency in MHz of the given channel and base frequency. ++ * The channel number is interpreted relative to the given base frequency. ++ * ++ * The valid channel range is [1, 14] in the 2.4 GHz band and [0, 200] otherwise. ++ * The base frequency is specified as (start_factor * 500 kHz). ++ * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G are defined for ++ * 2.4 GHz and 5 GHz bands. ++ * The channel range of [1, 14] is only checked for a start_factor of ++ * WF_CHAN_FACTOR_2_4_G (4814). ++ * Odd start_factors produce channels on .5 MHz boundaries, in which case ++ * the answer is rounded down to an integral MHz. ++ * -1 is returned for an out of range channel. ++ * ++ * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2 ++ * ++ * @param channel input channel number ++ * @param start_factor base frequency in 500 kHz units, e.g. 10000 for 5 GHz ++ * ++ * @return Returns a frequency in MHz ++ * ++ * @see WF_CHAN_FACTOR_2_4_G ++ * @see WF_CHAN_FACTOR_5_G ++ */ ++extern int wf_channel2mhz(uint channel, uint start_factor); ++ ++#endif /* _bcmwifi_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/compvers.sh b/drivers/net/ethernet/broadcom/gmac/src/include/compvers.sh +--- a/drivers/net/ethernet/broadcom/gmac/src/include/compvers.sh 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/compvers.sh 2017-11-09 17:53:43.943304000 +0800 +@@ -0,0 +1,133 @@ ++#!/bin/bash ++# ++# Given a list of components, generate _version.h ++# from version.h.in in 's directory ++# ++# Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++# ++# Permission to use, copy, modify, and/or distribute this software for any ++# purpose with or without fee is hereby granted, provided that the above ++# copyright notice and this permission notice appear in all copies. ++# ++# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++# ++# ++ ++# Optional argument ++ACTION=$1 ++[ -n "$VERBOSE" ] && export VERBOSE ++ ++SRCBASE=.. ++ ++# List of components ++# TODO: In the long term component versioning model, following list ++# TODO: or table of components will come from a central file ++COMPONENTS=( \ ++ upnp \ ++ phy \ ++ router \ ++ wps \ ++) ++ ++# Component dirs. Need one entry for each of above COMPONENTS ++COMPONENT_DIR_upnp=${SRCBASE}/router/libupnp/include ++COMPONENT_DIR_phy=${SRCBASE}/wl/phy ++COMPONENT_DIR_router=${SRCBASE}/router/shared ++COMPONENT_DIR_wps=${SRCBASE}/wps/common/include ++ ++# For a given component, query automerger for a different ++# path than COMPONENT_DIR_. ++# Force router component to be pointing to local branch or tag. ++COMPONENT_QUERY_router=src_force_local_component ++ ++ ++ ++# ===== DO NOT CHANGE ANYTHING BELOW THIS LINE ===== ++ ++NULL=/dev/null ++MKCOMPVER=${SRCBASE}/tools/release/mkversion.sh ++MERGERLOG=${SRCBASE}/../merger_sources.log ++ ++# TODO: Post svn transition, network paths will be taken away ++GETCOMPVER=getcompver.py ++GETCOMPVER_NET=/projects/hnd_software/gallery/src/tools/build/$GETCOMPVER ++GETCOMPVER_NET_WIN=Z:${GETCOMPVER_NET} ++ ++# ++# If there is a local copy GETCOMPVER use it ahead of network copy ++# ++if [ -s "$GETCOMPVER" ]; then ++ GETCOMPVER_PATH="$GETCOMPVER" ++elif [ -s "${SRCBASE}/../src/tools/build/$GETCOMPVER" ]; then ++ GETCOMPVER_PATH="${SRCBASE}/../src/tools/build/$GETCOMPVER" ++elif [ -s "$GETCOMPVER_NET" ]; then ++ GETCOMPVER_PATH="$GETCOMPVER_NET" ++elif [ -s "$GETCOMPVER_NET_WIN" ]; then ++ GETCOMPVER_PATH="$GETCOMPVER_NET_WIN" ++fi ++ ++# ++# If $GETCOMPVER isn't found, fetch it from SVN ++# (this is very rare) ++# ++if [ ! -s "$GETCOMPVER_PATH" ]; then ++ svn export -q \ ++ ^/proj/trunk/src/tools/build/${GETCOMPVER} \ ++ ${GETCOMPVER} 2> $NULL ++ GETCOMPVER_PATH=$GETCOMPVER ++fi ++ ++# ++# Now walk through each specified component to generate its ++# component_version.h file from version.h.in template ++# ++for component in ${COMPONENTS[*]} ++do ++ # Get relative path of component from current dir ++ tmp="COMPONENT_DIR_$component" ++ eval rel_path=\$$tmp ++ ++ # Get query path for component ++ tmp="COMPONENT_QUERY_$component" ++ eval query_path=\$$tmp ++ ++ if [ ! -d "$rel_path" ]; then ++ continue ++ fi ++ ++ if [ "$query_path" != "" ]; then ++ abs_path=$(echo $query_path | sed -e "s%\.\.%src%g") ++ else ++ abs_path=$(echo $rel_path | sed -e "s%\.\.%src%g") ++ fi ++ ++ [ -n "$VERBOSE" ] && \ ++ echo "DBG: python $GETCOMPVER_PATH $MERGERLOG $abs_path" ++ ++ tag=$(python $GETCOMPVER_PATH $MERGERLOG $abs_path 2> $NULL | sed -e 's/[[:space:]]*//g') ++ ++ template=$rel_path/version.h.in ++ verfile=$rel_path/${component}_version.h ++ ++ if [ "$ACTION" == "clean" ]; then ++ rm -fv $verfile ++ continue ++ fi ++ ++ # MKCOMPVER always has defaults if tag isn't set correctly ++ if [ ! -f "$verfile" -o "$FORCE" != "" ]; then ++ echo "" ++ echo ">>> Generate $abs_path/${component}_version.h from $tag" ++ ++ [ -n "$VERBOSE" ] && \ ++ echo "DBG: bash $MKCOMPVER $template $verfile $tag" ++ ++ bash $MKCOMPVER $template $verfile $tag ++ fi ++done +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/epivers.h b/drivers/net/ethernet/broadcom/gmac/src/include/epivers.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/epivers.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/epivers.h 2017-11-09 17:53:43.944299000 +0800 +@@ -0,0 +1,45 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * $Id: epivers.h.in,v 13.33 2010-09-08 22:08:53 $ ++*/ ++ ++#ifndef _epivers_h_ ++#define _epivers_h_ ++ ++#define EPI_MAJOR_VERSION 6 ++ ++#define EPI_MINOR_VERSION 30 ++ ++#define EPI_RC_NUMBER 40 ++ ++#define EPI_INCREMENTAL_NUMBER 0 ++ ++#define EPI_BUILD_NUMBER 2 ++ ++#define EPI_VERSION 6, 30, 40, 0 ++ ++#define EPI_VERSION_NUM 0x061e2800 ++ ++#define EPI_VERSION_DEV 6.30.40 ++ ++/* Driver Version String, ASCII, 32 chars max */ ++#ifdef WLTEST ++#define EPI_VERSION_STR "6.30.40 (TOB) (r WLTEST)" ++#else ++#define EPI_VERSION_STR "6.30.40 (TOB) (r)" ++#endif ++ ++#endif /* _epivers_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/epivers.h.in b/drivers/net/ethernet/broadcom/gmac/src/include/epivers.h.in +--- a/drivers/net/ethernet/broadcom/gmac/src/include/epivers.h.in 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/epivers.h.in 2017-11-09 17:53:43.945295000 +0800 +@@ -0,0 +1,46 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * $Id: epivers.h.in,v 13.33 2010-09-08 22:08:53 $ ++ * ++*/ ++ ++#ifndef _epivers_h_ ++#define _epivers_h_ ++ ++#define EPI_MAJOR_VERSION @EPI_MAJOR_VERSION@ ++ ++#define EPI_MINOR_VERSION @EPI_MINOR_VERSION@ ++ ++#define EPI_RC_NUMBER @EPI_RC_NUMBER@ ++ ++#define EPI_INCREMENTAL_NUMBER @EPI_INCREMENTAL_NUMBER@ ++ ++#define EPI_BUILD_NUMBER @EPI_BUILD_NUMBER@ ++ ++#define EPI_VERSION @EPI_VERSION@ ++ ++#define EPI_VERSION_NUM @EPI_VERSION_NUM@ ++ ++#define EPI_VERSION_DEV @EPI_VERSION_DEV@ ++ ++/* Driver Version String, ASCII, 32 chars max */ ++#ifdef WLTEST ++#define EPI_VERSION_STR "@EPI_VERSION_STR@@EPI_VERSION_TYPE@ (@VC_VERSION_NUM@ WLTEST)" ++#else ++#define EPI_VERSION_STR "@EPI_VERSION_STR@@EPI_VERSION_TYPE@ (@VC_VERSION_NUM@)" ++#endif ++ ++#endif /* _epivers_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/epivers.sh b/drivers/net/ethernet/broadcom/gmac/src/include/epivers.sh +--- a/drivers/net/ethernet/broadcom/gmac/src/include/epivers.sh 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/epivers.sh 2017-11-09 17:53:43.946291000 +0800 +@@ -0,0 +1,309 @@ ++#! /bin/bash ++# ++# Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++# ++# Permission to use, copy, modify, and/or distribute this software for any ++# purpose with or without fee is hereby granted, provided that the above ++# copyright notice and this permission notice appear in all copies. ++# ++# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++# ++# Create the epivers.h file from epivers.h.in ++# ++# Epivers.h generation mechanism supports svn based checkouts ++# ++# $Id: epivers.sh 299409 2011-11-30 00:52:43Z $ ++# ++# GetCompVer.py return value and action needed ++# i. trunk => use current date as version string ++# ii. local => use SVNURL expanded by HeadURL keyword ++# iii. => use it as as is ++# (some components can override and say give me native ver) ++# iv. empty => ++# a) If TAG is specified use it ++# a) If no TAG is specified use date ++# ++ ++# If the version header file already exists, increment its build number. ++# Otherwise, create a new file. ++if [ -f epivers.h ]; then ++ ++ # If REUSE_VERSION is set, epivers iteration is not incremented ++ # This can be used precommit and continuous integration projects ++ if [ -n "$REUSE_VERSION" ]; then ++ echo "Previous epivers.h exists. Skipping version increment" ++ exit 0 ++ fi ++ ++ build=`grep EPI_BUILD_NUMBER epivers.h | sed -e "s,.*BUILD_NUMBER[ ]*,,"` ++ build=`expr ${build} + 1` ++ echo build=${build} ++ sed -e "s,.*_BUILD_NUMBER.*,#define EPI_BUILD_NUMBER ${build}," \ ++ < epivers.h > epivers.h.new ++ mv epivers.h epivers.h.prev ++ mv epivers.h.new epivers.h ++ exit 0 ++ ++else # epivers.h doesn't exist ++ ++ NULL="/dev/null" ++ svncmd="svn --non-interactive" ++ ++ # Check for the in file, if not there we're in the wrong directory ++ if [ ! -f epivers.h.in ]; then ++ echo "ERROR: No epivers.h.in found" ++ exit 1 ++ fi ++ ++ # Following SVNURL should be expanded on checkout ++ SVNURL='$HeadURL: http://svn.sj.broadcom.com/svn/wlansvn/users/kenlo/northstar/AARDVARK_TWIG_6_30_40/src/include/epivers.sh $' ++ ++ # If SVNURL isn't expanded, extract it from svn info ++ if echo "$SVNURL" | grep -vq '$.*HeadURL.*epivers.sh.*$'; then ++ [ -n "$VERBOSE" ] && \ ++ echo "DBG: SVN URL wasn't expanded. Getting it from svn info" ++ SVNURL=$($svncmd info epivers.sh 2> $NULL | egrep "^URL:") ++ fi ++ ++ if echo "${TAG}" | grep -q "_BRANCH_\|_TWIG_"; then ++ branchtag=$TAG ++ else ++ branchtag="" ++ fi ++ ++ # If this is a tagged build, use the tag to supply the numbers ++ # Tag should be in the form ++ # _REL__ ++ # or ++ # _REL___RC ++ # or ++ # _REL___RC_ ++ ++ SRCBASE=.. ++ MERGERLOG=${SRCBASE}/../merger_sources.log ++ GETCOMPVER=getcompver.py ++ GETCOMPVER_NET=/projects/hnd_software/gallery/src/tools/build/$GETCOMPVER ++ GETCOMPVER_NET_WIN=Z:${GETCOMPVER_NET} ++ ++ # ++ # If there is a local copy GETCOMPVER use it ahead of network copy ++ # ++ if [ -s "$GETCOMPVER" ]; then ++ GETCOMPVER_PATH="$GETCOMPVER" ++ elif [ -s "${SRCBASE}/../src/tools/build/$GETCOMPVER" ]; then ++ GETCOMPVER_PATH="${SRCBASE}/../src/tools/build/$GETCOMPVER" ++ elif [ -s "$GETCOMPVER_NET" ]; then ++ GETCOMPVER_PATH="$GETCOMPVER_NET" ++ elif [ -s "$GETCOMPVER_NET_WIN" ]; then ++ GETCOMPVER_PATH="$GETCOMPVER_NET_WIN" ++ fi ++ ++ # ++ # If $GETCOMPVER isn't found, fetch it from SVN ++ # (this should be very rare) ++ # ++ if [ ! -s "$GETCOMPVER_PATH" ]; then ++ [ -n "$VERBOSE" ] && \ ++ echo "DBG: Fetching $GETCOMPVER from trunk" ++ ++ $svncmd export -q \ ++ ^/proj/trunk/src/tools/build/${GETCOMPVER} \ ++ ${GETCOMPVER} 2> $NULL ++ ++ GETCOMPVER_PATH=$GETCOMPVER ++ fi ++ ++ # Now get tag for src/include from automerger log ++ [ -n "$VERBOSE" ] && \ ++ echo "DBG: python $GETCOMPVER_PATH $MERGERLOG src/include" ++ ++ COMPTAG=$(python $GETCOMPVER_PATH $MERGERLOG src/include 2> $NULL | sed -e 's/[[:space:]]*//g') ++ ++ echo "DBG: Component Tag String Derived = $COMPTAG" ++ ++ # Process COMPTAG values ++ # Rule: ++ # If trunk is returned, use date as component tag ++ # If LOCAL_COMPONENT is returned, use SVN URL to get native tag ++ # If component is returned or empty, assign it to SVNTAG ++ # GetCompVer.py return value and action needed ++ # i. trunk => use current date as version string ++ # ii. local => use SVNURL expanded by HeadURL keyword ++ # iii. => use it as as is ++ # iv. empty => ++ # a) If TAG is specified use it ++ # a) If no TAG is specified use SVNURL from HeadURL ++ ++ SVNURL_VER=false ++ ++ if [ "$COMPTAG" == "" ]; then ++ SVNURL_VER=true ++ elif [ "$COMPTAG" == "LOCAL_COMPONENT" ]; then ++ SVNURL_VER=true ++ elif [ "$COMPTAG" == "trunk" ]; then ++ SVNTAG=$(date '+TRUNKCOMP_REL_%Y_%m_%d') ++ else ++ SVNTAG=$COMPTAG ++ fi ++ ++ # Given SVNURL path conventions or naming conventions, derive SVNTAG ++ # TO-DO: SVNTAG derivation logic can move to a central common API ++ # TO-DO: ${SRCBASE}/tools/build/svnurl2tag.sh ++ if [ "$SVNURL_VER" == "true" ]; then ++ case "${SVNURL}" in ++ */branches/*) ++ SVNTAG=$(echo $SVNURL | sed -e 's%.*/branches/\(.*\)/src.*%\1%g' | xargs printf "%s") ++ ;; ++ *_BRANCH_*) ++ SVNTAG=$(echo $SVNURL | sed -e 's%/%\n%g' | egrep _BRANCH_ | xargs printf "%s") ++ ;; ++ *_TWIG_*) ++ SVNTAG=$(echo $SVNURL | sed -e 's%/%\n%g' | egrep _TWIG_ | xargs printf "%s") ++ ;; ++ */tags/*) ++ SVNTAG=$(echo $SVNURL | sed -e 's%.*/tags/.*/\(.*\)/src.*%\1%g' | xargs printf "%s") ++ ;; ++ *_REL_*) ++ SVNTAG=$(echo $SVNURL | sed -e 's%/%\n%g' | egrep _REL_ | xargs printf "%s") ++ ;; ++ */trunk/*) ++ SVNTAG=$(date '+TRUNKURL_REL_%Y_%m_%d') ++ ;; ++ *) ++ SVNTAG=$(date '+OTHER_REL_%Y_%m_%d') ++ ;; ++ esac ++ echo "DBG: Native Tag String Derived from URL: $SVNTAG" ++ else ++ echo "DBG: Native Tag String Derived: $SVNTAG" ++ fi ++ ++ TAG=${SVNTAG} ++ ++ # Normalize the branch name portion to "D11" in case it has underscores in it ++ branch_name=`expr match "$TAG" '\(.*\)_\(BRANCH\|TWIG\|REL\)_.*'` ++ TAG=`echo $TAG | sed -e "s%^$branch_name%D11%"` ++ ++ # Split the tag into an array on underbar or whitespace boundaries. ++ IFS="_ " tag=(${TAG}) ++ unset IFS ++ ++ tagged=1 ++ if [ ${#tag[*]} -eq 0 ]; then ++ tag=(`date '+TOT REL %Y %m %d 0 %y'`); ++ # reconstruct a TAG from the date ++ TAG=${tag[0]}_${tag[1]}_${tag[2]}_${tag[3]}_${tag[4]}_${tag[5]} ++ tagged=0 ++ fi ++ ++ # Allow environment variable to override values. ++ # Missing values default to 0 ++ # ++ maj=${EPI_MAJOR_VERSION:-${tag[2]:-0}} ++ min=${EPI_MINOR_VERSION:-${tag[3]:-0}} ++ rcnum=${EPI_RC_NUMBER:-${tag[4]:-0}} ++ ++ # If increment field is 0, set it to date suffix if on TOB ++ if [ -n "$branchtag" ]; then ++ [ "${tag[5]:-0}" -eq 0 ] && echo "Using date suffix for incr" ++ today=`date '+%Y%m%d'` ++ incremental=${EPI_INCREMENTAL_NUMBER:-${tag[5]:-${today:-0}}} ++ else ++ incremental=${EPI_INCREMENTAL_NUMBER:-${tag[5]:-0}} ++ fi ++ origincr=${EPI_INCREMENTAL_NUMBER:-${tag[5]:-0}} ++ build=${EPI_BUILD_NUMBER:-0} ++ ++ # Strip 'RC' from front of rcnum if present ++ rcnum=${rcnum/#RC/} ++ ++ # strip leading zero off the number (otherwise they look like octal) ++ maj=${maj/#0/} ++ min=${min/#0/} ++ rcnum=${rcnum/#0/} ++ incremental=${incremental/#0/} ++ origincr=${origincr/#0/} ++ build=${build/#0/} ++ ++ # some numbers may now be null. replace with with zero. ++ maj=${maj:-0} ++ min=${min:-0} ++ ++ rcnum=${rcnum:-0} ++ incremental=${incremental:-0} ++ origincr=${origincr:-0} ++ build=${build:-0} ++ ++ if [ ${tagged} -eq 1 ]; then ++ # vernum is 32chars max ++ vernum=`printf "0x%02x%02x%02x%02x" ${maj} ${min} ${rcnum} ${origincr}` ++ else ++ vernum=`printf "0x00%02x%02x%02x" ${tag[7]} ${min} ${rcnum}` ++ fi ++ ++ # make sure the size of vernum is under 32 bits. ++ # Otherwise, truncate. The string will keep full information. ++ vernum=${vernum:0:10} ++ ++ # build the string directly from the tag, irrespective of its length ++ # remove the name , the tag type, then replace all _ by . ++ tag_ver_str=${TAG/${tag[0]}_} ++ tag_ver_str=${tag_ver_str/${tag[1]}_} ++ tag_ver_str=${tag_ver_str//_/.} ++ ++ # record tag type ++ tagtype= ++ ++ if [ "${tag[1]}" = "BRANCH" -o "${tag[1]}" = "TWIG" ]; then ++ tagtype=" (TOB)" ++ echo "tag type: $tagtype" ++ fi ++ ++ echo "Effective version string: $tag_ver_str" ++ ++ if [ "$(uname -s)" == "Darwin" ]; then ++ # Mac does not like 2-digit numbers so convert the number to single ++ # digit. 5.100 becomes 5.1 ++ if [ $min -gt 99 ]; then ++ minmac=`expr $min / 100` ++ else ++ minmac=$min ++ fi ++ epi_ver_dev="${maj}.${minmac}.0" ++ else ++ epi_ver_dev="${maj}.${min}.${rcnum}" ++ fi ++ ++ # Finally get version control revision number of (if any) ++ vc_version_num=$($svncmd info ${SRCBASE} 2> $NULL | awk -F': ' '/^Revision: /{printf "%s", $2}') ++ ++ # OK, go do it ++ echo "maj=${maj}, min=${min}, rc=${rcnum}, inc=${incremental}, build=${build}" ++ ++ sed \ ++ -e "s;@EPI_MAJOR_VERSION@;${maj};" \ ++ -e "s;@EPI_MINOR_VERSION@;${min};" \ ++ -e "s;@EPI_RC_NUMBER@;${rcnum};" \ ++ -e "s;@EPI_INCREMENTAL_NUMBER@;${incremental};" \ ++ -e "s;@EPI_BUILD_NUMBER@;${build};" \ ++ -e "s;@EPI_VERSION@;${maj}, ${min}, ${rcnum}, ${incremental};" \ ++ -e "s;@EPI_VERSION_STR@;${tag_ver_str};" \ ++ -e "s;@EPI_VERSION_TYPE@;${tagtype};" \ ++ -e "s;@VERSION_TYPE@;${tagtype};" \ ++ -e "s;@EPI_VERSION_NUM@;${vernum};" \ ++ -e "s;@EPI_VERSION_DEV@;${epi_ver_dev};" \ ++ -e "s;@VC_VERSION_NUM@;r${vc_version_num};" \ ++ < epivers.h.in > epivers.h ++ ++ # In shared workspaces across different platforms, ensure that ++ # windows generated file is made platform neutral without CRLF ++ if uname -s | egrep -i -q "cygwin"; then ++ dos2unix epivers.h > $NULL 2>&1 ++ fi ++fi # epivers.h +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/etioctl.h b/drivers/net/ethernet/broadcom/gmac/src/include/etioctl.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/etioctl.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/etioctl.h 2017-11-09 17:53:43.951293000 +0800 +@@ -0,0 +1,158 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * BCM44XX Ethernet Windows device driver custom OID definitions. ++ * ++ * $Id: etioctl.h 322208 2012-03-20 01:53:23Z $ ++ */ ++ ++#ifndef _etioctl_h_ ++#define _etioctl_h_ ++ ++/* ++ * Minor kludge alert: ++ * Duplicate a few definitions that irelay requires from epiioctl.h here ++ * so caller doesn't have to include this file and epiioctl.h . ++ * If this grows any more, it would be time to move these irelay-specific ++ * definitions out of the epiioctl.h and into a separate driver common file. ++ */ ++#ifndef EPICTRL_COOKIE ++#define EPICTRL_COOKIE 0xABADCEDE ++#endif ++ ++/* common ioctl definitions */ ++#define ETCUP 0 ++#define ETCDOWN 1 ++#define ETCLOOP 2 ++#define ETCDUMP 3 ++#define ETCSETMSGLEVEL 4 ++#define ETCPROMISC 5 ++#define ETCVAR 6 ++#define ETCSPEED 7 ++#define ETCPHYRD 9 ++#define ETCPHYWR 10 ++#define ETCQOS 11 ++#define ETCPHYRD2 12 ++#define ETCPHYWR2 13 ++#define ETCROBORD 14 ++#define ETCROBOWR 15 ++ ++/* ++ * A set of iovars defined for ET set/get ++ */ ++#define IOV_ET_POWER_SAVE_MODE 1 ++#define IOV_ET_CLEAR_DUMP 2 ++#define IOV_ET_ROBO_DEVID 3 ++#define IOV_PKTC 4 ++#define IOV_PKTCBND 5 ++#define IOV_COUNTERS 6 ++#define IOV_DUMP_CTF 7 ++ ++#if defined(linux) || defined(__ECOS) ++#define SIOCSETCUP (SIOCDEVPRIVATE + ETCUP) ++#define SIOCSETCDOWN (SIOCDEVPRIVATE + ETCDOWN) ++#define SIOCSETCLOOP (SIOCDEVPRIVATE + ETCLOOP) ++#define SIOCGETCDUMP (SIOCDEVPRIVATE + ETCDUMP) ++#define SIOCSETCSETMSGLEVEL (SIOCDEVPRIVATE + ETCSETMSGLEVEL) ++#define SIOCSETCPROMISC (SIOCDEVPRIVATE + ETCPROMISC) ++#define SIOCSETGETVAR (SIOCDEVPRIVATE + ETCVAR) ++#define SIOCSETCSPEED (SIOCDEVPRIVATE + ETCSPEED) ++#define SIOCTXGEN (SIOCDEVPRIVATE + 8) ++#define SIOCGETCPHYRD (SIOCDEVPRIVATE + ETCPHYRD) ++#define SIOCSETCPHYWR (SIOCDEVPRIVATE + ETCPHYWR) ++#define SIOCSETCQOS (SIOCDEVPRIVATE + ETCQOS) ++#define SIOCGETCPHYRD2 (SIOCDEVPRIVATE + ETCPHYRD2) ++#define SIOCSETCPHYWR2 (SIOCDEVPRIVATE + ETCPHYWR2) ++#define SIOCGETCROBORD (SIOCDEVPRIVATE + ETCROBORD) ++#define SIOCSETCROBOWR (SIOCDEVPRIVATE + ETCROBOWR) ++ ++/* structure to send a generic var set/get */ ++typedef struct et_var_s { ++ uint cmd; ++ uint set; ++ void *buf; ++ uint len; ++} et_var_t; ++ ++/* arg to SIOCTXGEN */ ++struct txg { ++ uint32 num; /* number of frames to send */ ++ uint32 delay; /* delay in microseconds between sending each */ ++ uint32 size; /* size of ether frame to send */ ++ uchar buf[1514]; /* starting ether frame data */ ++}; ++#endif /* linux */ ++ ++ ++#if defined(__NetBSD__) ++#define SIOCSETCUP _IOW('e', 0, struct ifreq) ++#define SIOCSETCDOWN _IOW('e', 1, struct ifreq) ++#define SIOCSETCLOOP _IOW('e', 2, struct ifreq) ++#define SIOCGETCDUMP _IOWR('e', 3, struct ifreq) ++#define SIOCSETCSETMSGLEVEL _IOW('e', 4, struct ifreq) ++#define SIOCSETCPROMISC _IOW('e', 5, struct ifreq) ++#define SIOCSETCTXDOWN _IOW('e', 6, struct ifreq) /* obsolete */ ++#define SIOCSETCSPEED _IOW('e', 7, struct ifreq) ++#define SIOCTXGEN _IOW('e', 8, struct ifreq) ++#define SIOCGETCPHYRD _IOWR('e', 9, struct ifreq) ++#define SIOCSETCPHYWR _IOW('e', 10, struct ifreq) ++#define SIOCSETCQOS _IOW('e', 11, struct ifreq) ++#define SIOCGETCPHYRD2 _IOWR('e', 12, struct ifreq) ++#define SIOCSETCPHYWR2 _IOW('e', 13, struct ifreq) ++#define SIOCGETCROBORD _IOWR('e', 14, struct ifreq) ++#define SIOCSETCROBOWR _IOW('e', 15, struct ifreq) ++ ++/* arg to SIOCTXGEN */ ++struct txg { ++ uint32 num; /* number of frames to send */ ++ uint32 delay; /* delay in microseconds between sending each */ ++ uint32 size; /* size of ether frame to send */ ++ uchar buf[1514]; /* starting ether frame data */ ++}; ++#endif /* __NetBSD__ */ ++ ++/* ++ * custom OID support ++ * ++ * 0xFF - implementation specific OID ++ * 0xE4 - first byte of Broadcom PCI vendor ID ++ * 0x14 - second byte of Broadcom PCI vendor ID ++ * 0xXX - the custom OID number ++ */ ++#define ET_OID_BASE 0xFFE41400 /* OID Base for ET */ ++ ++#define OID_ET_UP (ET_OID_BASE + ETCUP) ++#define OID_ET_DOWN (ET_OID_BASE + ETCDOWN) ++#define OID_ET_LOOP (ET_OID_BASE + ETCLOOP) ++#define OID_ET_DUMP (ET_OID_BASE + ETCDUMP) ++#define OID_ET_SETMSGLEVEL (ET_OID_BASE + ETCSETMSGLEVEL) ++#define OID_ET_PROMISC (ET_OID_BASE + ETCPROMISC) ++#define OID_ET_TXDOWN (ET_OID_BASE + 6) ++#define OID_ET_SPEED (ET_OID_BASE + ETCSPEED) ++#define OID_ET_GETINSTANCE (ET_OID_BASE + 8) ++#define OID_ET_SETCALLBACK (ET_OID_BASE + 9) ++#define OID_ET_UNSETCALLBACK (ET_OID_BASE + 10) ++ ++#define IS_ET_OID(oid) (((oid) & 0xFFFFFF00) == 0xFFE41400) ++ ++#define ET_ISQUERYOID(oid) ((oid == OID_ET_DUMP) || (oid == OID_ET_GETINSTANCE)) ++ ++/* OID_ET_SETCALLBACK data type */ ++typedef struct et_cb { ++ void (*fn)(void *, int); /* Callback function */ ++ void *context; /* Passed to callback function */ ++} et_cb_t; ++ ++#endif /* _etioctl_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/gmac_common.h b/drivers/net/ethernet/broadcom/gmac/src/include/gmac_common.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/gmac_common.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/gmac_common.h 2017-11-09 17:53:43.959311000 +0800 +@@ -0,0 +1,560 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * gmacdefs - Broadcom gmac (Unimac) specific definitions ++ * ++ * $Id: gmac_common.h 241182 2011-02-17 21:50:03Z $ ++ */ ++ ++#ifndef _gmac_common_core_h_ ++#define _gmac_common_core_h_ ++ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD XSTR(__LINE__) ++#endif ++ ++typedef volatile struct _gmac_commonregs { ++ uint32 stag0; ++ uint32 stag1; ++ uint32 stag2; ++ uint32 stag3; ++ uint32 PAD[4]; ++ uint32 parsercontrol; ++ uint32 mib_max_len; ++ uint32 PAD[54]; ++ uint32 phyaccess; ++ uint32 phycontrol; ++ uint32 PAD[2]; ++ uint32 gmac0_rgmii_cntl; ++ uint32 PAD[59]; ++ uint32 cfp_access; ++ uint32 PAD[3]; ++ uint32 cfp_tcam_data0; ++ uint32 cfp_tcam_data1; ++ uint32 cfp_tcam_data2; ++ uint32 cfp_tcam_data3; ++ uint32 cfp_tcam_data4; ++ uint32 cfp_tcam_data5; ++ uint32 cfp_tcam_data6; ++ uint32 cfp_tcam_data7; ++ uint32 cfp_tcam_mask0; ++ uint32 cfp_tcam_mask1; ++ uint32 cfp_tcam_mask2; ++ uint32 cfp_tcam_mask3; ++ uint32 cfp_tcam_mask4; ++ uint32 cfp_tcam_mask5; ++ uint32 cfp_tcam_mask6; ++ uint32 cfp_tcam_mask7; ++ uint32 cfp_action_data; ++ uint32 PAD[19]; ++ uint32 tcam_bist_cntl; ++ uint32 tcam_bist_status; ++ uint32 tcam_cmp_status; ++ uint32 tcam_disable; ++ uint32 PAD[16]; ++ uint32 tcam_test_cntl; ++ uint32 PAD[3]; ++ uint32 udf_0_a3_a0; ++ uint32 udf_0_a7_a4; ++ uint32 udf_0_a8; ++ uint32 PAD[1]; ++ uint32 udf_1_a3_a0; ++ uint32 udf_1_a7_a4; ++ uint32 udf_1_a8; ++ uint32 PAD[1]; ++ uint32 udf_2_a3_a0; ++ uint32 udf_2_a7_a4; ++ uint32 udf_2_a8; ++ uint32 PAD[1]; ++ uint32 udf_0_b3_b0; ++ uint32 udf_0_b7_b4; ++ uint32 udf_0_b8; ++ uint32 PAD[1]; ++ uint32 udf_1_b3_b0; ++ uint32 udf_1_b7_b4; ++ uint32 udf_1_b8; ++ uint32 PAD[1]; ++ uint32 udf_2_b3_b0; ++ uint32 udf_2_b7_b4; ++ uint32 udf_2_b8; ++ uint32 PAD[1]; ++ uint32 udf_0_c3_c0; ++ uint32 udf_0_c7_c4; ++ uint32 udf_0_c8; ++ uint32 PAD[1]; ++ uint32 udf_1_c3_c0; ++ uint32 udf_1_c7_c4; ++ uint32 udf_1_c8; ++ uint32 PAD[1]; ++ uint32 udf_2_c3_c0; ++ uint32 udf_2_c7_c4; ++ uint32 udf_2_c8; ++ uint32 PAD[1]; ++ uint32 udf_0_d3_d0; ++ uint32 udf_0_d7_d4; ++ uint32 udf_0_d11_d8; ++} gmac_commonregs_t; ++ ++/* stag0 offset0x0 */ ++#define STAG0_TPID_SHIFT 0 ++#define STAG0_TPID_MASK 0xffff ++ ++/* stag1 offset0x4 */ ++#define STAG1_TPID_SHIFT 0 ++#define STAG1_TPID_MASK 0xffff ++ ++/* stag2 offset0x8 */ ++#define STAG2_TPID_SHIFT 0 ++#define STAG2_TPID_MASK 0xffff ++ ++/* stag3 offset0xc */ ++#define STAG3_TPID_SHIFT 0 ++#define STAG3_TPID_MASK 0xffff ++ ++/* parsercontrol offset0x20 */ ++#define PARSERCONTROL_MAX_PARSER_LEN_TH_SHIFT 0 ++#define PARSERCONTROL_MAX_PARSER_LEN_TH_MASK 0x3fff ++ ++/* mib_max_len offset0x24 */ ++#define MIB_MAX_LEN_MIB_MAX_LEN_SHIFT 0 ++#define MIB_MAX_LEN_MIB_MAX_LEN_MASK 0x3fff ++ ++/* phyaccess offset0x100 */ ++#define PHYACCESS_TRIGGER_SHIFT 30 ++#define PHYACCESS_TRIGGER_MASK 0x40000000 ++#define PHYACCESS_WR_CMD_SHIFT 29 ++#define PHYACCESS_WR_CMD_MASK 0x20000000 ++#define PHYACCESS_CPU_REG_ADDR_SHIFT 24 ++#define PHYACCESS_CPU_REG_ADDR_MASK 0x1f000000 ++#define PHYACCESS_CPU_PHY_ADDR_SHIFT 16 ++#define PHYACCESS_CPU_PHY_ADDR_MASK 0x1f0000 ++#define PHYACCESS_ACC_DATA_SHIFT 0 ++#define PHYACCESS_ACC_DATA_MASK 0xffff ++ ++/* phycontrol offset0x104 */ ++#define PHYCONTROL_SD_ACCESS_EN_SHIFT 25 ++#define PHYCONTROL_SD_ACCESS_EN_MASK 0x2000000 ++#define PHYCONTROL_NWAY_AUTO_POLLING_EN_SHIFT 24 ++#define PHYCONTROL_NWAY_AUTO_POLLING_EN_MASK 0x1000000 ++#define PHYCONTROL_MDC_TRANSITION_EN_SHIFT 23 ++#define PHYCONTROL_MDC_TRANSITION_EN_MASK 0x800000 ++#define PHYCONTROL_MDC_CYCLE_TH_SHIFT 16 ++#define PHYCONTROL_MDC_CYCLE_TH_MASK 0x7f0000 ++#define PHYCONTROL_EXT_PHY_ADDR_SHIFT 0 ++#define PHYCONTROL_EXT_PHY_ADDR_MASK 0x1f ++ ++/* gmac0_rgmii_cntl offset0x110 */ ++#define GMAC0_RGMII_CNTL_TIMING_SEL_SHIFT 0 ++#define GMAC0_RGMII_CNTL_TIMING_SEL_MASK 0x1 ++#define GMAC0_RGMII_CNTL_RGMII_DLL_RXC_BYPASS_SHIFT 1 ++#define GMAC0_RGMII_CNTL_RGMII_DLL_RXC_BYPASS_MASK 0x2 ++#define GMAC0_RGMII_CNTL_BYPASS_2NS_DEL_SHIFT 2 ++#define GMAC0_RGMII_CNTL_BYPASS_2NS_DEL_MASK 0x4 ++#define GMAC0_RGMII_CNTL_DEL_STRB_SHIFT 3 ++#define GMAC0_RGMII_CNTL_DEL_STRB_MASK 0x8 ++#define GMAC0_RGMII_CNTL_DEL_VALUE_SHIFT 4 ++#define GMAC0_RGMII_CNTL_DEL_VALUE_MASK 0x70 ++#define GMAC0_RGMII_CNTL_DEL_ADDR_SHIFT 7 ++#define GMAC0_RGMII_CNTL_DEL_ADDR_MASK 0x780 ++ ++/* cfp_access offset0x200 */ ++#define CFP_ACCESS_OP_START_DONE_SHIFT 0 ++#define CFP_ACCESS_OP_START_DONE_MASK 0x1 ++#define CFP_ACCESS_OP_SEL_SHIFT 1 ++#define CFP_ACCESS_OP_SEL_MASK 0xe ++#define CFP_ACCESS_CFP_RAM_CLEAR_SHIFT 4 ++#define CFP_ACCESS_CFP_RAM_CLEAR_MASK 0x10 ++#define CFP_ACCESS_RESERVED1_SHIFT 5 ++#define CFP_ACCESS_RESERVED1_MASK 0x3e0 ++#define CFP_ACCESS_RAM_SEL_SHIFT 10 ++#define CFP_ACCESS_RAM_SEL_MASK 0x7c00 ++#define CFP_ACCESS_TCAM_RESET_SHIFT 15 ++#define CFP_ACCESS_TCAM_RESET_MASK 0x8000 ++#define CFP_ACCESS_XCESS_ADDR_SHIFT 16 ++#define CFP_ACCESS_XCESS_ADDR_MASK 0x1ff0000 ++#define CFP_ACCESS_RESERVED0_SHIFT 25 ++#define CFP_ACCESS_RESERVED0_MASK 0xe000000 ++#define CFP_ACCESS_RD_STATUS_SHIFT 28 ++#define CFP_ACCESS_RD_STATUS_MASK 0xf0000000 ++ ++/* cfp_tcam_data0 offset0x210 */ ++#define CFP_TCAM_DATA0_DATA_SHIFT 0 ++#define CFP_TCAM_DATA0_DATA_MASK 0xffffffff ++ ++/* cfp_tcam_data1 offset0x214 */ ++#define CFP_TCAM_DATA1_DATA_SHIFT 0 ++#define CFP_TCAM_DATA1_DATA_MASK 0xffffffff ++ ++/* cfp_tcam_data2 offset0x218 */ ++#define CFP_TCAM_DATA2_DATA_SHIFT 0 ++#define CFP_TCAM_DATA2_DATA_MASK 0xffffffff ++ ++/* cfp_tcam_data3 offset0x21c */ ++#define CFP_TCAM_DATA3_DATA_SHIFT 0 ++#define CFP_TCAM_DATA3_DATA_MASK 0xffffffff ++ ++/* cfp_tcam_data4 offset0x220 */ ++#define CFP_TCAM_DATA4_DATA_SHIFT 0 ++#define CFP_TCAM_DATA4_DATA_MASK 0xffffffff ++ ++/* cfp_tcam_data5 offset0x224 */ ++#define CFP_TCAM_DATA5_DATA_SHIFT 0 ++#define CFP_TCAM_DATA5_DATA_MASK 0xffffffff ++ ++/* cfp_tcam_data6 offset0x228 */ ++#define CFP_TCAM_DATA6_DATA_SHIFT 0 ++#define CFP_TCAM_DATA6_DATA_MASK 0xffffffff ++ ++/* cfp_tcam_data7 offset0x22c */ ++#define CFP_TCAM_DATA7_DATA_SHIFT 0 ++#define CFP_TCAM_DATA7_DATA_MASK 0xffffffff ++ ++/* cfp_tcam_mask0 offset0x230 */ ++#define CFP_TCAM_MASK0_DATA_SHIFT 0 ++#define CFP_TCAM_MASK0_DATA_MASK 0xffffffff ++ ++/* cfp_tcam_mask1 offset0x234 */ ++#define CFP_TCAM_MASK1_DATA_SHIFT 0 ++#define CFP_TCAM_MASK1_DATA_MASK 0xffffffff ++ ++/* cfp_tcam_mask2 offset0x238 */ ++#define CFP_TCAM_MASK2_DATA_SHIFT 0 ++#define CFP_TCAM_MASK2_DATA_MASK 0xffffffff ++ ++/* cfp_tcam_mask3 offset0x23c */ ++#define CFP_TCAM_MASK3_DATA_SHIFT 0 ++#define CFP_TCAM_MASK3_DATA_MASK 0xffffffff ++ ++/* cfp_tcam_mask4 offset0x240 */ ++#define CFP_TCAM_MASK4_DATA_SHIFT 0 ++#define CFP_TCAM_MASK4_DATA_MASK 0xffffffff ++ ++/* cfp_tcam_mask5 offset0x244 */ ++#define CFP_TCAM_MASK5_DATA_SHIFT 0 ++#define CFP_TCAM_MASK5_DATA_MASK 0xffffffff ++ ++/* cfp_tcam_mask6 offset0x248 */ ++#define CFP_TCAM_MASK6_DATA_SHIFT 0 ++#define CFP_TCAM_MASK6_DATA_MASK 0xffffffff ++ ++/* cfp_tcam_mask7 offset0x24c */ ++#define CFP_TCAM_MASK7_DATA_SHIFT 0 ++#define CFP_TCAM_MASK7_DATA_MASK 0xffffffff ++ ++/* cfp_action_data offset0x250 */ ++#define CFP_ACTION_DATA_CHAINID_SHIFT 0 ++#define CFP_ACTION_DATA_CHAINID_MASK 0xff ++#define CFP_ACTION_DATA_CHANNELID_SHIFT 8 ++#define CFP_ACTION_DATA_CHANNELID_MASK 0xf00 ++#define CFP_ACTION_DATA_DROP_SHIFT 12 ++#define CFP_ACTION_DATA_DROP_MASK 0x1000 ++#define CFP_ACTION_DATA_RESERVED_SHIFT 13 ++#define CFP_ACTION_DATA_RESERVED_MASK 0xffffe000 ++ ++/* tcam_bist_cntl offset0x2a0 */ ++#define TCAM_BIST_CNTL_TCAM_BIST_EN_SHIFT 0 ++#define TCAM_BIST_CNTL_TCAM_BIST_EN_MASK 0x1 ++#define TCAM_BIST_CNTL_TCAM_BIST_TCAM_SEL_SHIFT 1 ++#define TCAM_BIST_CNTL_TCAM_BIST_TCAM_SEL_MASK 0x6 ++#define TCAM_BIST_CNTL_RESERVED1_SHIFT 3 ++#define TCAM_BIST_CNTL_RESERVED1_MASK 0x8 ++#define TCAM_BIST_CNTL_TCAM_BIST_STATUS_SEL_SHIFT 4 ++#define TCAM_BIST_CNTL_TCAM_BIST_STATUS_SEL_MASK 0xf0 ++#define TCAM_BIST_CNTL_TCAM_BIST_SKIP_ERR_CNT_SHIFT 8 ++#define TCAM_BIST_CNTL_TCAM_BIST_SKIP_ERR_CNT_MASK 0xff00 ++#define TCAM_BIST_CNTL_TCAM_TEST_COMPARE_SHIFT 16 ++#define TCAM_BIST_CNTL_TCAM_TEST_COMPARE_MASK 0x10000 ++#define TCAM_BIST_CNTL_RESERVED_SHIFT 17 ++#define TCAM_BIST_CNTL_RESERVED_MASK 0x7ffe0000 ++#define TCAM_BIST_CNTL_TCAM_BIST_DONE_SHIFT 31 ++#define TCAM_BIST_CNTL_TCAM_BIST_DONE_MASK 0x80000000 ++ ++/* tcam_bist_status offset0x2a4 */ ++#define TCAM_BIST_STATUS_TCAM_BIST_STATUS_SHIFT 0 ++#define TCAM_BIST_STATUS_TCAM_BIST_STATUS_MASK 0xffff ++#define TCAM_BIST_STATUS_RESERVED_SHIFT 16 ++#define TCAM_BIST_STATUS_RESERVED_MASK 0xffff0000 ++ ++/* tcam_cmp_status offset0x2a8 */ ++#define TCAM_CMP_STATUS_TCAM_HIT_ADDR_SHIFT 0 ++#define TCAM_CMP_STATUS_TCAM_HIT_ADDR_MASK 0x1ff ++#define TCAM_CMP_STATUS_RESERVED2_SHIFT 9 ++#define TCAM_CMP_STATUS_RESERVED2_MASK 0x7e00 ++#define TCAM_CMP_STATUS_TCAM_HIT_SHIFT 15 ++#define TCAM_CMP_STATUS_TCAM_HIT_MASK 0x8000 ++#define TCAM_CMP_STATUS_RESERVED1_SHIFT 16 ++#define TCAM_CMP_STATUS_RESERVED1_MASK 0xffff0000 ++ ++/* tcam_disable offset0x2ac */ ++#define TCAM_DISABLE_TCAM_DISABLE_SHIFT 0 ++#define TCAM_DISABLE_TCAM_DISABLE_MASK 0xf ++#define TCAM_DISABLE_RESERVED_SHIFT 4 ++#define TCAM_DISABLE_RESERVED_MASK 0xfffffff0 ++ ++/* tcam_test_cntl offset0x2f0 */ ++#define TCAM_TEST_CNTL_TCAM_TEST_CNTL_SHIFT 0 ++#define TCAM_TEST_CNTL_TCAM_TEST_CNTL_MASK 0x7ff ++#define TCAM_TEST_CNTL_RESERVED_SHIFT 11 ++#define TCAM_TEST_CNTL_RESERVED_MASK 0xfffff800 ++ ++/* udf_0_a3_a0 offset0x300 */ ++#define UDF_0_A3_A0_CFG_UDF_0_A0_SHIFT 0 ++#define UDF_0_A3_A0_CFG_UDF_0_A0_MASK 0xff ++#define UDF_0_A3_A0_CFG_UDF_0_A1_SHIFT 8 ++#define UDF_0_A3_A0_CFG_UDF_0_A1_MASK 0xff00 ++#define UDF_0_A3_A0_CFG_UDF_0_A2_SHIFT 16 ++#define UDF_0_A3_A0_CFG_UDF_0_A2_MASK 0xff0000 ++#define UDF_0_A3_A0_CFG_UDF_0_A3_SHIFT 24 ++#define UDF_0_A3_A0_CFG_UDF_0_A3_MASK 0xff000000 ++ ++/* udf_0_a7_a4 offset0x304 */ ++#define UDF_0_A7_A4_CFG_UDF_0_A4_SHIFT 0 ++#define UDF_0_A7_A4_CFG_UDF_0_A4_MASK 0xff ++#define UDF_0_A7_A4_CFG_UDF_0_A5_SHIFT 8 ++#define UDF_0_A7_A4_CFG_UDF_0_A5_MASK 0xff00 ++#define UDF_0_A7_A4_CFG_UDF_0_A6_SHIFT 16 ++#define UDF_0_A7_A4_CFG_UDF_0_A6_MASK 0xff0000 ++#define UDF_0_A7_A4_CFG_UDF_0_A7_SHIFT 24 ++#define UDF_0_A7_A4_CFG_UDF_0_A7_MASK 0xff000000 ++ ++/* udf_0_a8 offset0x308 */ ++#define UDF_0_A8_CFG_UDF_0_A8_SHIFT 0 ++#define UDF_0_A8_CFG_UDF_0_A8_MASK 0xff ++ ++/* udf_1_a3_a0 offset0x310 */ ++#define UDF_1_A3_A0_CFG_UDF_1_A0_SHIFT 0 ++#define UDF_1_A3_A0_CFG_UDF_1_A0_MASK 0xff ++#define UDF_1_A3_A0_CFG_UDF_1_A1_SHIFT 8 ++#define UDF_1_A3_A0_CFG_UDF_1_A1_MASK 0xff00 ++#define UDF_1_A3_A0_CFG_UDF_1_A2_SHIFT 16 ++#define UDF_1_A3_A0_CFG_UDF_1_A2_MASK 0xff0000 ++#define UDF_1_A3_A0_CFG_UDF_1_A3_SHIFT 24 ++#define UDF_1_A3_A0_CFG_UDF_1_A3_MASK 0xff000000 ++ ++/* udf_1_a7_a4 offset0x314 */ ++#define UDF_1_A7_A4_CFG_UDF_1_A4_SHIFT 0 ++#define UDF_1_A7_A4_CFG_UDF_1_A4_MASK 0xff ++#define UDF_1_A7_A4_CFG_UDF_1_A5_SHIFT 8 ++#define UDF_1_A7_A4_CFG_UDF_1_A5_MASK 0xff00 ++#define UDF_1_A7_A4_CFG_UDF_1_A6_SHIFT 16 ++#define UDF_1_A7_A4_CFG_UDF_1_A6_MASK 0xff0000 ++#define UDF_1_A7_A4_CFG_UDF_1_A7_SHIFT 24 ++#define UDF_1_A7_A4_CFG_UDF_1_A7_MASK 0xff000000 ++ ++/* udf_1_a8 offset0x318 */ ++#define UDF_1_A8_CFG_UDF_1_A8_SHIFT 0 ++#define UDF_1_A8_CFG_UDF_1_A8_MASK 0xff ++ ++/* udf_2_a3_a0 offset0x320 */ ++#define UDF_2_A3_A0_CFG_UDF_2_A0_SHIFT 0 ++#define UDF_2_A3_A0_CFG_UDF_2_A0_MASK 0xff ++#define UDF_2_A3_A0_CFG_UDF_2_A1_SHIFT 8 ++#define UDF_2_A3_A0_CFG_UDF_2_A1_MASK 0xff00 ++#define UDF_2_A3_A0_CFG_UDF_2_A2_SHIFT 16 ++#define UDF_2_A3_A0_CFG_UDF_2_A2_MASK 0xff0000 ++#define UDF_2_A3_A0_CFG_UDF_2_A3_SHIFT 24 ++#define UDF_2_A3_A0_CFG_UDF_2_A3_MASK 0xff000000 ++ ++/* udf_2_a7_a4 offset0x324 */ ++#define UDF_2_A7_A4_CFG_UDF_2_A4_SHIFT 0 ++#define UDF_2_A7_A4_CFG_UDF_2_A4_MASK 0xff ++#define UDF_2_A7_A4_CFG_UDF_2_A5_SHIFT 8 ++#define UDF_2_A7_A4_CFG_UDF_2_A5_MASK 0xff00 ++#define UDF_2_A7_A4_CFG_UDF_2_A6_SHIFT 16 ++#define UDF_2_A7_A4_CFG_UDF_2_A6_MASK 0xff0000 ++#define UDF_2_A7_A4_CFG_UDF_2_A7_SHIFT 24 ++#define UDF_2_A7_A4_CFG_UDF_2_A7_MASK 0xff000000 ++ ++/* udf_2_a8 offset0x328 */ ++#define UDF_2_A8_CFG_UDF_2_A8_SHIFT 0 ++#define UDF_2_A8_CFG_UDF_2_A8_MASK 0xff ++ ++/* udf_0_b3_b0 offset0x330 */ ++#define UDF_0_B3_B0_CFG_UDF_0_B0_SHIFT 0 ++#define UDF_0_B3_B0_CFG_UDF_0_B0_MASK 0xff ++#define UDF_0_B3_B0_CFG_UDF_0_B1_SHIFT 8 ++#define UDF_0_B3_B0_CFG_UDF_0_B1_MASK 0xff00 ++#define UDF_0_B3_B0_CFG_UDF_0_B2_SHIFT 16 ++#define UDF_0_B3_B0_CFG_UDF_0_B2_MASK 0xff0000 ++#define UDF_0_B3_B0_CFG_UDF_0_B3_SHIFT 24 ++#define UDF_0_B3_B0_CFG_UDF_0_B3_MASK 0xff000000 ++ ++/* udf_0_b7_b4 offset0x334 */ ++#define UDF_0_B7_B4_CFG_UDF_0_B4_SHIFT 0 ++#define UDF_0_B7_B4_CFG_UDF_0_B4_MASK 0xff ++#define UDF_0_B7_B4_CFG_UDF_0_B5_SHIFT 8 ++#define UDF_0_B7_B4_CFG_UDF_0_B5_MASK 0xff00 ++#define UDF_0_B7_B4_CFG_UDF_0_B6_SHIFT 16 ++#define UDF_0_B7_B4_CFG_UDF_0_B6_MASK 0xff0000 ++#define UDF_0_B7_B4_CFG_UDF_0_B7_SHIFT 24 ++#define UDF_0_B7_B4_CFG_UDF_0_B7_MASK 0xff000000 ++ ++/* udf_0_b8 offset0x338 */ ++#define UDF_0_B8_CFG_UDF_0_B8_SHIFT 0 ++#define UDF_0_B8_CFG_UDF_0_B8_MASK 0xff ++ ++/* udf_1_b3_b0 offset0x340 */ ++#define UDF_1_B3_B0_CFG_UDF_1_B0_SHIFT 0 ++#define UDF_1_B3_B0_CFG_UDF_1_B0_MASK 0xff ++#define UDF_1_B3_B0_CFG_UDF_1_B1_SHIFT 8 ++#define UDF_1_B3_B0_CFG_UDF_1_B1_MASK 0xff00 ++#define UDF_1_B3_B0_CFG_UDF_1_B2_SHIFT 16 ++#define UDF_1_B3_B0_CFG_UDF_1_B2_MASK 0xff0000 ++#define UDF_1_B3_B0_CFG_UDF_1_B3_SHIFT 24 ++#define UDF_1_B3_B0_CFG_UDF_1_B3_MASK 0xff000000 ++ ++/* udf_1_b7_b4 offset0x344 */ ++#define UDF_1_B7_B4_CFG_UDF_1_B4_SHIFT 0 ++#define UDF_1_B7_B4_CFG_UDF_1_B4_MASK 0xff ++#define UDF_1_B7_B4_CFG_UDF_1_B5_SHIFT 8 ++#define UDF_1_B7_B4_CFG_UDF_1_B5_MASK 0xff00 ++#define UDF_1_B7_B4_CFG_UDF_1_B6_SHIFT 16 ++#define UDF_1_B7_B4_CFG_UDF_1_B6_MASK 0xff0000 ++#define UDF_1_B7_B4_CFG_UDF_1_B7_SHIFT 24 ++#define UDF_1_B7_B4_CFG_UDF_1_B7_MASK 0xff000000 ++ ++/* udf_1_b8 offset0x348 */ ++#define UDF_1_B8_CFG_UDF_1_B8_SHIFT 0 ++#define UDF_1_B8_CFG_UDF_1_B8_MASK 0xff ++ ++/* udf_2_b3_b0 offset0x350 */ ++#define UDF_2_B3_B0_CFG_UDF_2_B0_SHIFT 0 ++#define UDF_2_B3_B0_CFG_UDF_2_B0_MASK 0xff ++#define UDF_2_B3_B0_CFG_UDF_2_B1_SHIFT 8 ++#define UDF_2_B3_B0_CFG_UDF_2_B1_MASK 0xff00 ++#define UDF_2_B3_B0_CFG_UDF_2_B2_SHIFT 16 ++#define UDF_2_B3_B0_CFG_UDF_2_B2_MASK 0xff0000 ++#define UDF_2_B3_B0_CFG_UDF_2_B3_SHIFT 24 ++#define UDF_2_B3_B0_CFG_UDF_2_B3_MASK 0xff000000 ++ ++/* udf_2_b7_b4 offset0x354 */ ++#define UDF_2_B7_B4_CFG_UDF_2_B4_SHIFT 0 ++#define UDF_2_B7_B4_CFG_UDF_2_B4_MASK 0xff ++#define UDF_2_B7_B4_CFG_UDF_2_B5_SHIFT 8 ++#define UDF_2_B7_B4_CFG_UDF_2_B5_MASK 0xff00 ++#define UDF_2_B7_B4_CFG_UDF_2_B6_SHIFT 16 ++#define UDF_2_B7_B4_CFG_UDF_2_B6_MASK 0xff0000 ++#define UDF_2_B7_B4_CFG_UDF_2_B7_SHIFT 24 ++#define UDF_2_B7_B4_CFG_UDF_2_B7_MASK 0xff000000 ++ ++/* udf_2_b8 offset0x358 */ ++#define UDF_2_B8_CFG_UDF_2_B8_SHIFT 0 ++#define UDF_2_B8_CFG_UDF_2_B8_MASK 0xff ++ ++/* udf_0_c3_c0 offset0x360 */ ++#define UDF_0_C3_C0_CFG_UDF_0_C0_SHIFT 0 ++#define UDF_0_C3_C0_CFG_UDF_0_C0_MASK 0xff ++#define UDF_0_C3_C0_CFG_UDF_0_C1_SHIFT 8 ++#define UDF_0_C3_C0_CFG_UDF_0_C1_MASK 0xff00 ++#define UDF_0_C3_C0_CFG_UDF_0_C2_SHIFT 16 ++#define UDF_0_C3_C0_CFG_UDF_0_C2_MASK 0xff0000 ++#define UDF_0_C3_C0_CFG_UDF_0_C3_SHIFT 24 ++#define UDF_0_C3_C0_CFG_UDF_0_C3_MASK 0xff000000 ++ ++/* udf_0_c7_c4 offset0x364 */ ++#define UDF_0_C7_C4_CFG_UDF_0_C4_SHIFT 0 ++#define UDF_0_C7_C4_CFG_UDF_0_C4_MASK 0xff ++#define UDF_0_C7_C4_CFG_UDF_0_C5_SHIFT 8 ++#define UDF_0_C7_C4_CFG_UDF_0_C5_MASK 0xff00 ++#define UDF_0_C7_C4_CFG_UDF_0_C6_SHIFT 16 ++#define UDF_0_C7_C4_CFG_UDF_0_C6_MASK 0xff0000 ++#define UDF_0_C7_C4_CFG_UDF_0_C7_SHIFT 24 ++#define UDF_0_C7_C4_CFG_UDF_0_C7_MASK 0xff000000 ++ ++/* udf_0_c8 offset0x368 */ ++#define UDF_0_C8_CFG_UDF_0_C8_SHIFT 0 ++#define UDF_0_C8_CFG_UDF_0_C8_MASK 0xff ++ ++/* udf_1_c3_c0 offset0x370 */ ++#define UDF_1_C3_C0_CFG_UDF_1_C0_SHIFT 0 ++#define UDF_1_C3_C0_CFG_UDF_1_C0_MASK 0xff ++#define UDF_1_C3_C0_CFG_UDF_1_C1_SHIFT 8 ++#define UDF_1_C3_C0_CFG_UDF_1_C1_MASK 0xff00 ++#define UDF_1_C3_C0_CFG_UDF_1_C2_SHIFT 16 ++#define UDF_1_C3_C0_CFG_UDF_1_C2_MASK 0xff0000 ++#define UDF_1_C3_C0_CFG_UDF_1_C3_SHIFT 24 ++#define UDF_1_C3_C0_CFG_UDF_1_C3_MASK 0xff000000 ++ ++/* udf_1_c7_c4 offset0x374 */ ++#define UDF_1_C7_C4_CFG_UDF_1_C4_SHIFT 0 ++#define UDF_1_C7_C4_CFG_UDF_1_C4_MASK 0xff ++#define UDF_1_C7_C4_CFG_UDF_1_C5_SHIFT 8 ++#define UDF_1_C7_C4_CFG_UDF_1_C5_MASK 0xff00 ++#define UDF_1_C7_C4_CFG_UDF_1_C6_SHIFT 16 ++#define UDF_1_C7_C4_CFG_UDF_1_C6_MASK 0xff0000 ++#define UDF_1_C7_C4_CFG_UDF_1_C7_SHIFT 24 ++#define UDF_1_C7_C4_CFG_UDF_1_C7_MASK 0xff000000 ++ ++/* udf_1_c8 offset0x378 */ ++#define UDF_1_C8_CFG_UDF_1_C8_SHIFT 0 ++#define UDF_1_C8_CFG_UDF_1_C8_MASK 0xff ++ ++/* udf_2_c3_c0 offset0x380 */ ++#define UDF_2_C3_C0_CFG_UDF_2_C0_SHIFT 0 ++#define UDF_2_C3_C0_CFG_UDF_2_C0_MASK 0xff ++#define UDF_2_C3_C0_CFG_UDF_2_C1_SHIFT 8 ++#define UDF_2_C3_C0_CFG_UDF_2_C1_MASK 0xff00 ++#define UDF_2_C3_C0_CFG_UDF_2_C2_SHIFT 16 ++#define UDF_2_C3_C0_CFG_UDF_2_C2_MASK 0xff0000 ++#define UDF_2_C3_C0_CFG_UDF_2_C3_SHIFT 24 ++#define UDF_2_C3_C0_CFG_UDF_2_C3_MASK 0xff000000 ++ ++/* udf_2_c7_c4 offset0x384 */ ++#define UDF_2_C7_C4_CFG_UDF_2_C4_SHIFT 0 ++#define UDF_2_C7_C4_CFG_UDF_2_C4_MASK 0xff ++#define UDF_2_C7_C4_CFG_UDF_2_C5_SHIFT 8 ++#define UDF_2_C7_C4_CFG_UDF_2_C5_MASK 0xff00 ++#define UDF_2_C7_C4_CFG_UDF_2_C6_SHIFT 16 ++#define UDF_2_C7_C4_CFG_UDF_2_C6_MASK 0xff0000 ++#define UDF_2_C7_C4_CFG_UDF_2_C7_SHIFT 24 ++#define UDF_2_C7_C4_CFG_UDF_2_C7_MASK 0xff000000 ++ ++/* udf_2_c8 offset0x388 */ ++#define UDF_2_C8_CFG_UDF_2_C8_SHIFT 0 ++#define UDF_2_C8_CFG_UDF_2_C8_MASK 0xff ++ ++/* udf_0_d3_d0 offset0x390 */ ++#define UDF_0_D3_D0_CFG_UDF_0_D0_SHIFT 0 ++#define UDF_0_D3_D0_CFG_UDF_0_D0_MASK 0xff ++#define UDF_0_D3_D0_CFG_UDF_0_D1_SHIFT 8 ++#define UDF_0_D3_D0_CFG_UDF_0_D1_MASK 0xff00 ++#define UDF_0_D3_D0_CFG_UDF_0_D2_SHIFT 16 ++#define UDF_0_D3_D0_CFG_UDF_0_D2_MASK 0xff0000 ++#define UDF_0_D3_D0_CFG_UDF_0_D3_SHIFT 24 ++#define UDF_0_D3_D0_CFG_UDF_0_D3_MASK 0xff000000 ++ ++/* udf_0_d7_d4 offset0x394 */ ++#define UDF_0_D7_D4_CFG_UDF_0_D4_SHIFT 0 ++#define UDF_0_D7_D4_CFG_UDF_0_D4_MASK 0xff ++#define UDF_0_D7_D4_CFG_UDF_0_D5_SHIFT 8 ++#define UDF_0_D7_D4_CFG_UDF_0_D5_MASK 0xff00 ++#define UDF_0_D7_D4_CFG_UDF_0_D6_SHIFT 16 ++#define UDF_0_D7_D4_CFG_UDF_0_D6_MASK 0xff0000 ++#define UDF_0_D7_D4_CFG_UDF_0_D7_SHIFT 24 ++#define UDF_0_D7_D4_CFG_UDF_0_D7_MASK 0xff000000 ++ ++/* udf_0_d11_d8 offset0x398 */ ++#define UDF_0_D11_D8_CFG_UDF_0_D8_SHIFT 0 ++#define UDF_0_D11_D8_CFG_UDF_0_D8_MASK 0xff ++#define UDF_0_D11_D8_CFG_UDF_0_D9_SHIFT 8 ++#define UDF_0_D11_D8_CFG_UDF_0_D9_MASK 0xff00 ++#define UDF_0_D11_D8_CFG_UDF_0_D10_SHIFT 16 ++#define UDF_0_D11_D8_CFG_UDF_0_D10_MASK 0xff0000 ++#define UDF_0_D11_D8_CFG_UDF_0_D11_SHIFT 24 ++#define UDF_0_D11_D8_CFG_UDF_0_D11_MASK 0xff000000 ++ ++#endif /* _gmac_common_core_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/gmac_core.h b/drivers/net/ethernet/broadcom/gmac/src/include/gmac_core.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/gmac_core.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/gmac_core.h 2017-11-09 17:53:43.960313000 +0800 +@@ -0,0 +1,304 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * gmacdefs - Broadcom gmac (Unimac) specific definitions ++ * ++ * $Id: gmac_core.h 241182 2011-02-17 21:50:03Z $ ++ */ ++ ++#ifndef _gmac_core_h_ ++#define _gmac_core_h_ ++ ++ ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif /* PAD */ ++ ++/* We have 4 DMA TX channels */ ++#define GMAC_NUM_DMA_TX 4 ++ ++typedef volatile struct { ++ dma64regs_t dmaxmt; /* dma tx */ ++ uint32 PAD[2]; ++ dma64regs_t dmarcv; /* dma rx */ ++ uint32 PAD[2]; ++} dma64_t; ++ ++/* ++ * Host Interface Registers ++ */ ++typedef volatile struct _gmacregs { ++ uint32 devcontrol; /* 0x000 */ ++ uint32 devstatus; /* 0x004 */ ++ uint32 PAD; ++ uint32 biststatus; /* 0x00c */ ++ uint32 PAD[4]; ++ uint32 intstatus; /* 0x020 */ ++ uint32 intmask; /* 0x024 */ ++ uint32 gptimer; /* 0x028 */ ++ uint32 PAD[53]; ++ uint32 intrecvlazy; /* 0x100 */ ++ uint32 flowctlthresh; /* 0x104 */ ++ uint32 wrrthresh; /* 0x108 */ ++ uint32 gmac_idle_cnt_thresh; /* 0x10c */ ++ uint32 PAD[28]; ++ uint32 phyaccess; /* 0x180 */ ++ uint32 PAD; ++ uint32 phycontrol; /* 0x188 */ ++ uint32 txqctl; /* 0x18c */ ++ uint32 rxqctl; /* 0x190 */ ++ uint32 gpioselect; /* 0x194 */ ++ uint32 gpio_output_en; /* 0x198 */ ++ uint32 PAD; /* 0x19c */ ++ uint32 txq_rxq_mem_ctl; /* 0x1a0 */ ++ uint32 memory_ecc_status; /* 0x1a4 */ ++ uint32 serdes_ctl; /* 0x1a8 */ ++ uint32 serdes_status0; /* 0x1ac */ ++ uint32 serdes_status1; /* 0x1b0 */ ++ uint32 PAD[11]; /* 0x1b4-1dc */ ++ uint32 clk_ctl_st; /* 0x1e0 */ ++ uint32 hw_war; /* 0x1e4 */ ++ uint32 pwrctl; /* 0x1e8 */ ++ uint32 PAD[5]; ++ ++ dma64_t dmaregs[GMAC_NUM_DMA_TX]; ++ ++ /* GAMC MIB counters */ ++ gmacmib_t mib; ++ uint32 PAD[245]; ++ ++ uint32 unimacversion; /* 0x800 */ ++ uint32 hdbkpctl; /* 0x804 */ ++ uint32 cmdcfg; /* 0x808 */ ++ uint32 macaddrhigh; /* 0x80c */ ++ uint32 macaddrlow; /* 0x810 */ ++ uint32 rxmaxlength; /* 0x814 */ ++ uint32 pausequanta; /* 0x818 */ ++ uint32 PAD[10]; ++ uint32 macmode; /* 0x844 */ ++ uint32 outertag; /* 0x848 */ ++ uint32 innertag; /* 0x84c */ ++ uint32 PAD[3]; ++ uint32 txipg; /* 0x85c */ ++ uint32 PAD[180]; ++ uint32 pausectl; /* 0xb30 */ ++ uint32 txflush; /* 0xb34 */ ++ uint32 rxstatus; /* 0xb38 */ ++ uint32 txstatus; /* 0xb3c */ ++} gmacregs_t; ++ ++#define GM_MIB_BASE 0x300 ++#define GM_MIB_LIMIT 0x800 ++ ++/* ++ * register-specific flag definitions ++ */ ++ ++/* device control */ ++#define DC_TSM 0x00000002 ++#define DC_CFCO 0x00000004 ++#define DC_RLSS 0x00000008 ++#define DC_MROR 0x00000010 ++#define DC_FCM_MASK 0x00000060 ++#define DC_FCM_SHIFT 5 ++#define DC_NAE 0x00000080 ++#define DC_TF 0x00000100 ++#define DC_RDS_MASK 0x00030000 ++#define DC_RDS_SHIFT 16 ++#define DC_TDS_MASK 0x000c0000 ++#define DC_TDS_SHIFT 18 ++ ++/* device status */ ++#define DS_RBF 0x00000001 ++#define DS_RDF 0x00000002 ++#define DS_RIF 0x00000004 ++#define DS_TBF 0x00000008 ++#define DS_TDF 0x00000010 ++#define DS_TIF 0x00000020 ++#define DS_PO 0x00000040 ++#define DS_MM_MASK 0x00000300 ++#define DS_MM_SHIFT 8 ++ ++/* bist status */ ++#define BS_MTF 0x00000001 ++#define BS_MRF 0x00000002 ++#define BS_TDB 0x00000004 ++#define BS_TIB 0x00000008 ++#define BS_TBF 0x00000010 ++#define BS_RDB 0x00000020 ++#define BS_RIB 0x00000040 ++#define BS_RBF 0x00000080 ++#define BS_URTF 0x00000100 ++#define BS_UTF 0x00000200 ++#define BS_URF 0x00000400 ++ ++/* interrupt status and mask registers */ ++#define I_MRO 0x00000001 ++#define I_MTO 0x00000002 ++#define I_TFD 0x00000004 ++#define I_LS 0x00000008 ++#define I_MDIO 0x00000010 ++#define I_MR 0x00000020 ++#define I_MT 0x00000040 ++#define I_TO 0x00000080 ++#define I_PDEE 0x00000400 ++#define I_PDE 0x00000800 ++#define I_DE 0x00001000 ++#define I_RDU 0x00002000 ++#define I_RFO 0x00004000 ++#define I_XFU 0x00008000 ++#define I_RI 0x00010000 ++#define I_XI0 0x01000000 ++#define I_XI1 0x02000000 ++#define I_XI2 0x04000000 ++#define I_XI3 0x08000000 ++#define I_INTMASK 0x0f01fcff ++#define I_ERRMASK 0x0000fc00 ++ ++/* interrupt receive lazy */ ++#define IRL_TO_MASK 0x00ffffff ++#define IRL_FC_MASK 0xff000000 ++#define IRL_FC_SHIFT 24 ++ ++/* flow control thresholds */ ++#define FCT_TT_MASK 0x00000fff ++#define FCT_RT_MASK 0x0fff0000 ++#define FCT_RT_SHIFT 16 ++ ++/* txq aribter wrr thresholds */ ++#define WRRT_Q0T_MASK 0x000000ff ++#define WRRT_Q1T_MASK 0x0000ff00 ++#define WRRT_Q1T_SHIFT 8 ++#define WRRT_Q2T_MASK 0x00ff0000 ++#define WRRT_Q2T_SHIFT 16 ++#define WRRT_Q3T_MASK 0xff000000 ++#define WRRT_Q3T_SHIFT 24 ++ ++/* phy access */ ++#define PA_DATA_MASK 0x0000ffff ++#define PA_ADDR_MASK 0x001f0000 ++#define PA_ADDR_SHIFT 16 ++#define PA_REG_MASK 0x1f000000 ++#define PA_REG_SHIFT 24 ++#define PA_WRITE 0x20000000 ++#define PA_START 0x40000000 ++ ++/* phy control */ ++#define PC_EPA_MASK 0x0000001f ++#define PC_MCT_MASK 0x007f0000 ++#define PC_MCT_SHIFT 16 ++#define PC_MTE 0x00800000 ++ ++/* rxq control */ ++#define RC_DBT_MASK 0x00000fff ++#define RC_DBT_SHIFT 0 ++#define RC_PTE 0x00001000 ++#define RC_MDP_MASK 0x3f000000 ++#define RC_MDP_SHIFT 24 ++ ++#define RC_MAC_DATA_PERIOD 9 ++ ++/* txq control */ ++#define TC_DBT_MASK 0x00000fff ++#define TC_DBT_SHIFT 0 ++ ++/* gpio select */ ++#define GS_GSC_MASK 0x0000000f ++#define GS_GSC_SHIFT 0 ++ ++/* gpio output enable */ ++#define GS_GOE_MASK 0x0000ffff ++#define GS_GOE_SHIFT 0 ++ ++/* gpio output enable */ ++#define SC_TX1G_FIFO_RST_MASK 0x00f00000 ++#define SC_TX1G_FIFO_RST_VAL 0x00f00000 ++#define SC_FORCE_SPD_STRAP_MASK 0x00060000 ++#define SC_FORCE_SPD_STRAP_VAL 0x00040000 ++#define SC_FORCE_SPD_100M_VAL 0x00020000 ++#define SC_FORCE_SPD_1G_VAL 0x00040000 ++#define SC_REF_TERM_SEL_MASK 0x00001000 ++#define SC_REFSEL_MASK 0x00000c00 ++#define SC_REFSEL_VAL 0x00000400 ++#define SC_REFDIV_MASK 0x00000300 ++#define SC_REFDIV_VAL 0x00000000 ++#define SC_LCREF_EN_MASK 0x00000040 ++#define SC_RSTB_PLL_MASK 0x00000010 ++#define SC_RSTB_MDIOREGS_MASK 0x00000008 ++#define SC_RSTB_HW_MASK 0x00000004 ++#define SC_IDDQ_MASK 0x00000002 ++#define SC_PWR_DOWN_MASK 0x00000001 ++ ++/* clk control status */ ++#define CS_FA 0x00000001 ++#define CS_FH 0x00000002 ++#define CS_FI 0x00000004 ++#define CS_AQ 0x00000008 ++#define CS_HQ 0x00000010 ++#define CS_FC 0x00000020 ++#define CS_ER 0x00000100 ++#define CS_AA 0x00010000 ++#define CS_HA 0x00020000 ++#define CS_BA 0x00040000 ++#define CS_BH 0x00080000 ++#define CS_ES 0x01000000 ++ ++/* command config */ ++#define CC_TE 0x00000001 ++#define CC_RE 0x00000002 ++#define CC_ES_MASK 0x0000000c ++#define CC_ES_SHIFT 2 ++#define CC_PROM 0x00000010 ++#define CC_PAD_EN 0x00000020 ++#define CC_CF 0x00000040 ++#define CC_PF 0x00000080 ++#define CC_RPI 0x00000100 ++#define CC_TAI 0x00000200 ++#define CC_HD 0x00000400 ++#define CC_HD_SHIFT 10 ++#define CC_SR 0x00002000 ++#define CC_ML 0x00008000 ++#define CC_OT 0x00020000 ++#define CC_OR 0x00040000 ++#define CC_AE 0x00400000 ++#define CC_CFE 0x00800000 ++#define CC_NLC 0x01000000 ++#define CC_RL 0x02000000 ++#define CC_RED 0x04000000 ++#define CC_PE 0x08000000 ++#define CC_TPI 0x10000000 ++#define CC_AT 0x20000000 ++ ++/* mac addr high */ ++#define MH_HI_MASK 0xffff ++#define MH_HI_SHIFT 16 ++#define MH_MID_MASK 0xffff ++#define MH_MID_SHIFT 0 ++ ++/* mac addr low */ ++#define ML_LO_MASK 0xffff ++#define ML_LO_SHIFT 0 ++ ++/* Core specific control flags */ ++#define SICF_SWCLKE 0x0004 ++#define SICF_SWRST 0x0008 ++ ++/* Core specific status flags */ ++#define SISF_SW_ATTACHED 0x0800 ++ ++#endif /* _gmac_core_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/hndarm.h b/drivers/net/ethernet/broadcom/gmac/src/include/hndarm.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/hndarm.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/hndarm.h 2017-11-09 17:53:43.961300000 +0800 +@@ -0,0 +1,96 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * HND SiliconBackplane ARM core software interface. ++ * ++ * $Id: hndarm.h 325951 2012-04-05 06:03:27Z $ ++ */ ++ ++#ifndef _hndarm_h_ ++#define _hndarm_h_ ++ ++#include ++ ++extern void *hndarm_armr; ++extern uint32 hndarm_rev; ++ ++ ++extern void si_arm_init(si_t *sih); ++ ++#ifdef __ARM_ARCH_7A__ ++extern uint32 si_memc_get_ncdl(si_t *sih); ++#endif ++ ++extern void enable_arm_ints(uint32 which); ++extern void disable_arm_ints(uint32 which); ++ ++extern uint32 get_arm_cyclecount(void); ++extern void set_arm_cyclecount(uint32 ticks); ++ ++#ifdef __ARM_ARCH_7R__ ++extern uint32 get_arm_perfcount_enable(void); ++extern void set_arm_perfcount_enable(uint32 which); ++extern uint32 set_arm_perfcount_disable(void); ++ ++extern uint32 get_arm_perfcount_sel(void); ++extern void set_arm_perfcount_sel(uint32 which); ++ ++extern uint32 get_arm_perfcount_event(void); ++extern void set_arm_perfcount_event(uint32 which); ++ ++extern uint32 get_arm_perfcount(void); ++extern void set_arm_perfcount(uint32 which); ++ ++extern void enable_arm_cyclecount(void); ++extern void disable_arm_cyclecount(void); ++#endif /* __ARM_ARCH_7R__ */ ++ ++extern uint32 get_arm_inttimer(void); ++extern void set_arm_inttimer(uint32 ticks); ++ ++extern uint32 get_arm_intmask(void); ++extern void set_arm_intmask(uint32 ticks); ++ ++extern uint32 get_arm_intstatus(void); ++extern void set_arm_intstatus(uint32 ticks); ++ ++extern uint32 get_arm_firqmask(void); ++extern void set_arm_firqmask(uint32 ticks); ++ ++extern uint32 get_arm_firqstatus(void); ++extern void set_arm_firqstatus(uint32 ticks); ++ ++extern void arm_wfi(si_t *sih); ++extern void arm_jumpto(void *addr); ++ ++extern void traptest(void); ++ ++#ifdef BCMOVLHW ++#define BCMOVLHW_ENAB(sih) TRUE ++ ++extern int si_arm_ovl_remap(si_t *sih, void *virt, void *phys, uint size); ++extern int si_arm_ovl_reset(si_t *sih); ++extern bool si_arm_ovl_vaildaddr(si_t *sih, void *virt); ++extern bool si_arm_ovl_isenab(si_t *sih); ++extern bool si_arm_ovl_int(si_t *sih, uint32 pc); ++#else ++#define BCMOVLHW_ENAB(sih) FALSE ++ ++#define si_arm_ovl_remap(a, b, c, d) do {} while (0) ++#define si_arm_ovl_reset(a) do {} while (0) ++#define si_arm_ovl_int(a, b) FALSE ++#endif ++ ++#endif /* _hndarm_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/hndchipc.h b/drivers/net/ethernet/broadcom/gmac/src/include/hndchipc.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/hndchipc.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/hndchipc.h 2017-11-09 17:53:43.962303000 +0800 +@@ -0,0 +1,38 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * HND SiliconBackplane chipcommon support. ++ * ++ * $Id: hndchipc.h 241182 2011-02-17 21:50:03Z $ ++ */ ++ ++#ifndef _hndchipc_h_ ++#define _hndchipc_h_ ++ ++typedef void (*si_serial_init_fn)(void *regs, uint irq, uint baud_base, uint reg_shift); ++ ++extern void si_serial_init(si_t *sih, si_serial_init_fn add); ++ ++extern void *hnd_jtagm_init(si_t *sih, uint clkd, bool exttap); ++extern void hnd_jtagm_disable(si_t *sih, void *h); ++extern uint32 jtag_scan(si_t *sih, void *h, uint irsz, uint32 ir0, uint32 ir1, ++ uint drsz, uint32 dr0, uint32 *dr1, bool rti); ++ ++typedef void (*cc_isr_fn)(void* cbdata, uint32 ccintst); ++ ++extern bool si_cc_register_isr(si_t *sih, cc_isr_fn isr, uint32 ccintmask, void *cbdata); ++extern void si_cc_isr(si_t *sih, chipcregs_t *regs); ++ ++#endif /* _hndchipc_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/hndcpu.h b/drivers/net/ethernet/broadcom/gmac/src/include/hndcpu.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/hndcpu.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/hndcpu.h 2017-11-09 17:53:43.963297000 +0800 +@@ -0,0 +1,40 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * HND SiliconBackplane MIPS/ARM cores software interface. ++ * ++ * $Id: hndcpu.h 258983 2011-05-11 09:59:25Z $ ++ */ ++ ++#ifndef _hndcpu_h_ ++#define _hndcpu_h_ ++ ++#if defined(mips) ++#include ++#elif defined(__arm__) || defined(__thumb__) || defined(__thumb2__) ++#include ++#endif ++ ++extern uint si_irq(si_t *sih); ++extern uint32 si_cpu_clock(si_t *sih); ++extern uint32 si_mem_clock(si_t *sih); ++extern void hnd_cpu_wait(si_t *sih); ++extern void hnd_cpu_jumpto(void *addr); ++extern void hnd_cpu_reset(si_t *sih); ++extern void hnd_cpu_deadman_timer(si_t *sih, uint32 val); ++extern void si_router_coma(si_t *sih, int reset, int delay); ++extern void si_dmc_phyctl(si_t *sih, uint32 phyctl_val); ++ ++#endif /* _hndcpu_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/hnddma.h b/drivers/net/ethernet/broadcom/gmac/src/include/hnddma.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/hnddma.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/hnddma.h 2017-11-09 17:53:43.964295000 +0800 +@@ -0,0 +1,317 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Generic Broadcom Home Networking Division (HND) DMA engine SW interface ++ * This supports the following chips: BCM42xx, 44xx, 47xx . ++ * ++ * $Id: hnddma.h 321146 2012-03-14 08:27:23Z $ ++ */ ++ ++#ifndef _hnddma_h_ ++#define _hnddma_h_ ++ ++#ifndef _hnddma_pub_ ++#define _hnddma_pub_ ++typedef const struct hnddma_pub hnddma_t; ++#endif /* _hnddma_pub_ */ ++ ++/* range param for dma_getnexttxp() and dma_txreclaim */ ++typedef enum txd_range { ++ HNDDMA_RANGE_ALL = 1, ++ HNDDMA_RANGE_TRANSMITTED, ++ HNDDMA_RANGE_TRANSFERED ++} txd_range_t; ++ ++/* dma parameters id */ ++enum dma_param_id { ++ HNDDMA_PID_TX_MULTI_OUTSTD_RD = 0, ++ HNDDMA_PID_TX_PREFETCH_CTL, ++ HNDDMA_PID_TX_PREFETCH_THRESH, ++ HNDDMA_PID_TX_BURSTLEN, ++ ++ HNDDMA_PID_RX_PREFETCH_CTL = 0x100, ++ HNDDMA_PID_RX_PREFETCH_THRESH, ++ HNDDMA_PID_RX_BURSTLEN ++}; ++ ++/* dma function type */ ++typedef void (*di_detach_t)(hnddma_t *dmah); ++typedef bool (*di_txreset_t)(hnddma_t *dmah); ++typedef bool (*di_rxreset_t)(hnddma_t *dmah); ++typedef bool (*di_rxidle_t)(hnddma_t *dmah); ++typedef void (*di_txinit_t)(hnddma_t *dmah); ++typedef bool (*di_txenabled_t)(hnddma_t *dmah); ++typedef void (*di_rxinit_t)(hnddma_t *dmah); ++typedef void (*di_txsuspend_t)(hnddma_t *dmah); ++typedef void (*di_txresume_t)(hnddma_t *dmah); ++typedef bool (*di_txsuspended_t)(hnddma_t *dmah); ++typedef bool (*di_txsuspendedidle_t)(hnddma_t *dmah); ++#ifdef WL_MULTIQUEUE ++typedef void (*di_txflush_t)(hnddma_t *dmah); ++typedef void (*di_txflush_clear_t)(hnddma_t *dmah); ++#endif /* WL_MULTIQUEUE */ ++typedef int (*di_txfast_t)(hnddma_t *dmah, void *p, bool commit); ++typedef int (*di_txunframed_t)(hnddma_t *dmah, void *p, uint len, bool commit); ++typedef int (*di_rxunframed_t)(hnddma_t *dmah, void *p, uint len, bool commit); ++typedef void* (*di_getpos_t)(hnddma_t *di, bool direction); ++typedef void (*di_fifoloopbackenable_t)(hnddma_t *dmah); ++typedef bool (*di_txstopped_t)(hnddma_t *dmah); ++typedef bool (*di_rxstopped_t)(hnddma_t *dmah); ++typedef bool (*di_rxenable_t)(hnddma_t *dmah); ++typedef bool (*di_rxenabled_t)(hnddma_t *dmah); ++typedef void* (*di_rx_t)(hnddma_t *dmah); ++typedef bool (*di_rxfill_t)(hnddma_t *dmah); ++typedef void (*di_txreclaim_t)(hnddma_t *dmah, txd_range_t range); ++typedef void (*di_rxreclaim_t)(hnddma_t *dmah); ++typedef uintptr (*di_getvar_t)(hnddma_t *dmah, const char *name); ++typedef void* (*di_getnexttxp_t)(hnddma_t *dmah, txd_range_t range); ++typedef void* (*di_getnextrxp_t)(hnddma_t *dmah, bool forceall); ++typedef void* (*di_peeknexttxp_t)(hnddma_t *dmah); ++typedef void* (*di_peekntxp_t)(hnddma_t *dmah, int *len, void *txps[], txd_range_t range); ++typedef void* (*di_peeknextrxp_t)(hnddma_t *dmah); ++typedef void (*di_rxparam_get_t)(hnddma_t *dmah, uint16 *rxoffset, uint16 *rxbufsize); ++typedef void (*di_txblock_t)(hnddma_t *dmah); ++typedef void (*di_txunblock_t)(hnddma_t *dmah); ++typedef uint (*di_txactive_t)(hnddma_t *dmah); ++typedef void (*di_txrotate_t)(hnddma_t *dmah); ++typedef void (*di_counterreset_t)(hnddma_t *dmah); ++typedef uint (*di_ctrlflags_t)(hnddma_t *dmah, uint mask, uint flags); ++typedef char* (*di_dump_t)(hnddma_t *dmah, struct bcmstrbuf *b, bool dumpring); ++typedef char* (*di_dumptx_t)(hnddma_t *dmah, struct bcmstrbuf *b, bool dumpring); ++typedef char* (*di_dumprx_t)(hnddma_t *dmah, struct bcmstrbuf *b, bool dumpring); ++typedef uint (*di_rxactive_t)(hnddma_t *dmah); ++typedef uint (*di_txpending_t)(hnddma_t *dmah); ++typedef uint (*di_txcommitted_t)(hnddma_t *dmah); ++typedef int (*di_pktpool_set_t)(hnddma_t *dmah, pktpool_t *pool); ++typedef bool (*di_rxtxerror_t)(hnddma_t *dmah, bool istx); ++typedef void (*di_burstlen_set_t)(hnddma_t *dmah, uint8 rxburstlen, uint8 txburstlen); ++typedef uint (*di_avoidancecnt_t)(hnddma_t *dmah); ++typedef void (*di_param_set_t)(hnddma_t *dmah, uint16 paramid, uint16 paramval); ++typedef bool (*dma_glom_enable_t) (hnddma_t *dmah, uint32 val); ++typedef uint (*dma_active_rxbuf_t) (hnddma_t *dmah); ++/* dma opsvec */ ++typedef struct di_fcn_s { ++ di_detach_t detach; ++ di_txinit_t txinit; ++ di_txreset_t txreset; ++ di_txenabled_t txenabled; ++ di_txsuspend_t txsuspend; ++ di_txresume_t txresume; ++ di_txsuspended_t txsuspended; ++ di_txsuspendedidle_t txsuspendedidle; ++#ifdef WL_MULTIQUEUE ++ di_txflush_t txflush; ++ di_txflush_clear_t txflush_clear; ++#endif /* WL_MULTIQUEUE */ ++ di_txfast_t txfast; ++ di_txunframed_t txunframed; ++ di_getpos_t getpos; ++ di_txstopped_t txstopped; ++ di_txreclaim_t txreclaim; ++ di_getnexttxp_t getnexttxp; ++ di_peeknexttxp_t peeknexttxp; ++ di_peekntxp_t peekntxp; ++ di_txblock_t txblock; ++ di_txunblock_t txunblock; ++ di_txactive_t txactive; ++ di_txrotate_t txrotate; ++ ++ di_rxinit_t rxinit; ++ di_rxreset_t rxreset; ++ di_rxidle_t rxidle; ++ di_rxstopped_t rxstopped; ++ di_rxenable_t rxenable; ++ di_rxenabled_t rxenabled; ++ di_rx_t rx; ++ di_rxfill_t rxfill; ++ di_rxreclaim_t rxreclaim; ++ di_getnextrxp_t getnextrxp; ++ di_peeknextrxp_t peeknextrxp; ++ di_rxparam_get_t rxparam_get; ++ ++ di_fifoloopbackenable_t fifoloopbackenable; ++ di_getvar_t d_getvar; ++ di_counterreset_t counterreset; ++ di_ctrlflags_t ctrlflags; ++ di_dump_t dump; ++ di_dumptx_t dumptx; ++ di_dumprx_t dumprx; ++ di_rxactive_t rxactive; ++ di_txpending_t txpending; ++ di_txcommitted_t txcommitted; ++ di_pktpool_set_t pktpool_set; ++ di_rxtxerror_t rxtxerror; ++ di_burstlen_set_t burstlen_set; ++ di_avoidancecnt_t avoidancecnt; ++ di_param_set_t param_set; ++ dma_glom_enable_t glom_enab; ++ di_rxunframed_t rxunframed; ++ dma_active_rxbuf_t dma_activerxbuf; ++ uint endnum; ++} di_fcn_t; ++ ++/* ++ * Exported data structure (read-only) ++ */ ++/* export structure */ ++struct hnddma_pub { ++ const di_fcn_t *di_fn; /* DMA function pointers */ ++ uint txavail; /* # free tx descriptors */ ++ uint dmactrlflags; /* dma control flags */ ++ ++ /* rx error counters */ ++ uint rxgiants; /* rx giant frames */ ++ uint rxnobuf; /* rx out of dma descriptors */ ++ /* tx error counters */ ++ uint txnobuf; /* tx out of dma descriptors */ ++ uint txnodesc; /* tx out of dma descriptors running count */ ++}; ++ ++ ++extern hnddma_t * dma_attach(osl_t *osh, const char *name, si_t *sih, ++ volatile void *dmaregstx, volatile void *dmaregsrx, ++ uint ntxd, uint nrxd, uint rxbufsize, int rxextheadroom, uint nrxpost, ++ uint rxoffset, uint *msg_level); ++#ifdef BCMDMA32 ++ ++#define dma_detach(di) ((di)->di_fn->detach(di)) ++#define dma_txreset(di) ((di)->di_fn->txreset(di)) ++#define dma_rxreset(di) ((di)->di_fn->rxreset(di)) ++#define dma_rxidle(di) ((di)->di_fn->rxidle(di)) ++#define dma_txinit(di) ((di)->di_fn->txinit(di)) ++#define dma_txenabled(di) ((di)->di_fn->txenabled(di)) ++#define dma_rxinit(di) ((di)->di_fn->rxinit(di)) ++#define dma_txsuspend(di) ((di)->di_fn->txsuspend(di)) ++#define dma_txresume(di) ((di)->di_fn->txresume(di)) ++#define dma_txsuspended(di) ((di)->di_fn->txsuspended(di)) ++#define dma_txsuspendedidle(di) ((di)->di_fn->txsuspendedidle(di)) ++#ifdef WL_MULTIQUEUE ++#define dma_txflush(di) ((di)->di_fn->txflush(di)) ++#define dma_txflush_clear(di) ((di)->di_fn->txflush_clear(di)) ++#endif /* WL_MULTIQUEUE */ ++#define dma_txfast(di, p, commit) ((di)->di_fn->txfast(di, p, commit)) ++#define dma_fifoloopbackenable(di) ((di)->di_fn->fifoloopbackenable(di)) ++#define dma_txstopped(di) ((di)->di_fn->txstopped(di)) ++#define dma_rxstopped(di) ((di)->di_fn->rxstopped(di)) ++#define dma_rxenable(di) ((di)->di_fn->rxenable(di)) ++#define dma_rxenabled(di) ((di)->di_fn->rxenabled(di)) ++#define dma_rx(di) ((di)->di_fn->rx(di)) ++#define dma_rxfill(di) ((di)->di_fn->rxfill(di)) ++#define dma_txreclaim(di, range) ((di)->di_fn->txreclaim(di, range)) ++#define dma_rxreclaim(di) ((di)->di_fn->rxreclaim(di)) ++#define dma_getvar(di, name) ((di)->di_fn->d_getvar(di, name)) ++#define dma_getnexttxp(di, range) ((di)->di_fn->getnexttxp(di, range)) ++#define dma_getnextrxp(di, forceall) ((di)->di_fn->getnextrxp(di, forceall)) ++#define dma_peeknexttxp(di) ((di)->di_fn->peeknexttxp(di)) ++#define dma_peekntxp(di, l, t, r) ((di)->di_fn->peekntxp(di, l, t, r)) ++#define dma_peeknextrxp(di) ((di)->di_fn->peeknextrxp(di)) ++#define dma_rxparam_get(di, off, bufs) ((di)->di_fn->rxparam_get(di, off, bufs)) ++ ++#define dma_txblock(di) ((di)->di_fn->txblock(di)) ++#define dma_txunblock(di) ((di)->di_fn->txunblock(di)) ++#define dma_txactive(di) ((di)->di_fn->txactive(di)) ++#define dma_rxactive(di) ((di)->di_fn->rxactive(di)) ++#define dma_txrotate(di) ((di)->di_fn->txrotate(di)) ++#define dma_counterreset(di) ((di)->di_fn->counterreset(di)) ++#define dma_ctrlflags(di, mask, flags) ((di)->di_fn->ctrlflags((di), (mask), (flags))) ++#define dma_txpending(di) ((di)->di_fn->txpending(di)) ++#define dma_txcommitted(di) ((di)->di_fn->txcommitted(di)) ++#define dma_pktpool_set(di, pool) ((di)->di_fn->pktpool_set((di), (pool))) ++#if defined(BCMDBG) ++#define dma_dump(di, buf, dumpring) ((di)->di_fn->dump(di, buf, dumpring)) ++#define dma_dumptx(di, buf, dumpring) ((di)->di_fn->dumptx(di, buf, dumpring)) ++#define dma_dumprx(di, buf, dumpring) ((di)->di_fn->dumprx(di, buf, dumpring)) ++#endif ++#define dma_rxtxerror(di, istx) ((di)->di_fn->rxtxerror(di, istx)) ++#define dma_burstlen_set(di, rxlen, txlen) ((di)->di_fn->burstlen_set(di, rxlen, txlen)) ++#define dma_avoidance_cnt(di) ((di)->di_fn->avoidancecnt(di)) ++#define dma_param_set(di, paramid, paramval) ((di)->di_fn->param_set(di, paramid, paramval)) ++#define dma_activerxbuf(di) ((di)->di_fn->dma_activerxbuf(di)) ++ ++#else /* BCMDMA32 */ ++extern const di_fcn_t dma64proc; ++ ++#define dma_detach(di) (dma64proc.detach(di)) ++#define dma_txreset(di) (dma64proc.txreset(di)) ++#define dma_rxreset(di) (dma64proc.rxreset(di)) ++#define dma_rxidle(di) (dma64proc.rxidle(di)) ++#define dma_txinit(di) (dma64proc.txinit(di)) ++#define dma_txenabled(di) (dma64proc.txenabled(di)) ++#define dma_rxinit(di) (dma64proc.rxinit(di)) ++#define dma_txsuspend(di) (dma64proc.txsuspend(di)) ++#define dma_txresume(di) (dma64proc.txresume(di)) ++#define dma_txsuspended(di) (dma64proc.txsuspended(di)) ++#define dma_txsuspendedidle(di) (dma64proc.txsuspendedidle(di)) ++#ifdef WL_MULTIQUEUE ++#define dma_txflush(di) (dma64proc.txflush(di)) ++#define dma_txflush_clear(di) (dma64proc.txflush_clear(di)) ++#endif /* WL_MULTIQUEUE */ ++#define dma_txfast(di, p, commit) (dma64proc.txfast(di, p, commit)) ++#define dma_txunframed(di, p, l, commit)(dma64proc.txunframed(di, p, l, commit)) ++#define dma_getpos(di, dir) (dma64proc.getpos(di, dir)) ++#define dma_fifoloopbackenable(di) (dma64proc.fifoloopbackenable(di)) ++#define dma_txstopped(di) (dma64proc.txstopped(di)) ++#define dma_rxstopped(di) (dma64proc.rxstopped(di)) ++#define dma_rxenable(di) (dma64proc.rxenable(di)) ++#define dma_rxenabled(di) (dma64proc.rxenabled(di)) ++#define dma_rx(di) (dma64proc.rx(di)) ++#define dma_rxfill(di) (dma64proc.rxfill(di)) ++#define dma_txreclaim(di, range) (dma64proc.txreclaim(di, range)) ++#define dma_rxreclaim(di) (dma64proc.rxreclaim(di)) ++#define dma_getvar(di, name) (dma64proc.d_getvar(di, name)) ++#define dma_getnexttxp(di, range) (dma64proc.getnexttxp(di, range)) ++#define dma_getnextrxp(di, forceall) (dma64proc.getnextrxp(di, forceall)) ++#define dma_peeknexttxp(di) (dma64proc.peeknexttxp(di)) ++#define dma_peekntxp(di, l, t, r) (dma64proc.peekntxp(di, l, t, r)) ++#define dma_peeknextrxp(di) (dma64proc.peeknextrxp(di)) ++#define dma_rxparam_get(di, off, bufs) (dma64proc.rxparam_get(di, off, bufs)) ++ ++#define dma_txblock(di) (dma64proc.txblock(di)) ++#define dma_txunblock(di) (dma64proc.txunblock(di)) ++#define dma_txactive(di) (dma64proc.txactive(di)) ++#define dma_rxactive(di) (dma64proc.rxactive(di)) ++#define dma_txrotate(di) (dma64proc.txrotate(di)) ++#define dma_counterreset(di) (dma64proc.counterreset(di)) ++#define dma_ctrlflags(di, mask, flags) (dma64proc.ctrlflags((di), (mask), (flags))) ++#define dma_txpending(di) (dma64proc.txpending(di)) ++#define dma_txcommitted(di) (dma64proc.txcommitted(di)) ++#define dma_pktpool_set(di, pool) (dma64proc.pktpool_set((di), (pool))) ++#define dma_rxunframed(di, p, l, commit)(dma64proc.rxunframed(di, p, l, commit)) ++#if defined(BCMDBG) ++#define dma_dump(di, buf, dumpring) (dma64proc.dump(di, buf, dumpring)) ++#define dma_dumptx(di, buf, dumpring) (dma64proc.dumptx(di, buf, dumpring)) ++#define dma_dumprx(di, buf, dumpring) (dma64proc.dumprx(di, buf, dumpring)) ++#endif ++#define dma_rxtxerror(di, istx) (dma64proc.rxtxerror(di, istx)) ++#define dma_burstlen_set(di, rxlen, txlen) (dma64proc.burstlen_set(di, rxlen, txlen)) ++#define dma_avoidance_cnt(di) (dma64proc.avoidancecnt(di)) ++#define dma_param_set(di, paramid, paramval) (dma64proc.param_set(di, paramid, paramval)) ++ ++#define dma_glom_enable(di, val) (dma64proc.glom_enab(di, val)) ++#define dma_activerxbuf(di) (dma64proc.dma_activerxbuf(di)) ++ ++#endif /* BCMDMA32 */ ++ ++/* return addresswidth allowed ++ * This needs to be done after SB attach but before dma attach. ++ * SB attach provides ability to probe backplane and dma core capabilities ++ * This info is needed by DMA_ALLOC_CONSISTENT in dma attach ++ */ ++extern uint dma_addrwidth(si_t *sih, void *dmaregs); ++ ++/* pio helpers */ ++extern void dma_txpioloopback(osl_t *osh, dma32regs_t *); ++ ++#endif /* _hnddma_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/hndsoc.h b/drivers/net/ethernet/broadcom/gmac/src/include/hndsoc.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/hndsoc.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/hndsoc.h 2017-11-09 17:53:43.965312000 +0800 +@@ -0,0 +1,259 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Broadcom HND chip & on-chip-interconnect-related definitions. ++ * ++ * $Id: hndsoc.h 325951 2012-04-05 06:03:27Z $ ++ */ ++ ++#ifndef _HNDSOC_H ++#define _HNDSOC_H ++ ++/* Include the soci specific files */ ++#include ++#include ++ ++/* ++ * SOC Interconnect Address Map. ++ * All regions may not exist on all chips. ++ */ ++#define SI_SDRAM_BASE 0x00000000 /* Physical SDRAM */ ++#define SI_PCI_MEM 0x08000000 /* Host Mode sb2pcitranslation0 (64 MB) */ ++#define SI_PCI_MEM_SZ (64 * 1024 * 1024) ++#define SI_PCI_CFG 0x0c000000 /* Host Mode sb2pcitranslation1 (64 MB) */ ++#define SI_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */ ++#define SI_SDRAM_R2 0x80000000 /* Region 2 for sdram (512 MB) */ ++#define SI_ENUM_BASE 0x18000000 /* Enumeration space base */ ++#define SI_WRAP_BASE 0x18100000 /* Wrapper space base */ ++#define SI_CORE_SIZE 0x1000 /* each core gets 4Kbytes for registers */ ++#define SI_MAXCORES 20 /* Max cores (this is arbitrary, for software ++ * convenience and could be changed if we ++ * make any larger chips ++ */ ++ ++#define SI_FASTRAM 0x19000000 /* On-chip RAM on chips that also have DDR */ ++#define SI_FASTRAM_SWAPPED 0x19800000 ++ ++#define SI_FLASH2 0x1c000000 /* Flash Region 2 (region 1 shadowed here) */ ++#define SI_FLASH2_SZ 0x02000000 /* Size of Flash Region 2 */ ++#define SI_ARMCM3_ROM 0x1e000000 /* ARM Cortex-M3 ROM */ ++#define SI_FLASH1 0x1fc00000 /* MIPS Flash Region 1 */ ++#define SI_FLASH1_SZ 0x00400000 /* MIPS Size of Flash Region 1 */ ++ ++#define SI_NS_NANDFLASH 0x1c000000 /* NorthStar NAND flash base */ ++#define SI_NS_NORFLASH 0x1e000000 /* NorthStar NOR flash base */ ++#define SI_NS_NORFLASH_SZ 0x02000000 /* Size of NorthStar NOR flash region */ ++#define SI_NS_ROM 0xfffd0000 /* NorthStar ROM */ ++ ++#define SI_ARM7S_ROM 0x20000000 /* ARM7TDMI-S ROM */ ++#define SI_ARMCR4_ROM 0x000f0000 /* ARM Cortex-R4 ROM */ ++#define SI_ARMCM3_SRAM2 0x60000000 /* ARM Cortex-M3 SRAM Region 2 */ ++#define SI_ARM7S_SRAM2 0x80000000 /* ARM7TDMI-S SRAM Region 2 */ ++#define SI_ARM_FLASH1 0xffff0000 /* ARM Flash Region 1 */ ++#define SI_ARM_FLASH1_SZ 0x00010000 /* ARM Size of Flash Region 1 */ ++ ++#define SI_PCI_DMA 0x40000000 /* Client Mode sb2pcitranslation2 (1 GB) */ ++#define SI_PCI_DMA2 0x80000000 /* Client Mode sb2pcitranslation2 (1 GB) */ ++#define SI_PCI_DMA_SZ 0x40000000 /* Client Mode sb2pcitranslation2 size in bytes */ ++#define SI_PCIE_DMA_L32 0x00000000 /* PCIE Client Mode sb2pcitranslation2 ++ * (2 ZettaBytes), low 32 bits ++ */ ++#define SI_PCIE_DMA_H32 0x80000000 /* PCIE Client Mode sb2pcitranslation2 ++ * (2 ZettaBytes), high 32 bits ++ */ ++#define SI_NS_CUR 0x1800B000 /* NorthStar CUR base */ ++ ++#define SI_NS_CHIPCB_SRAB 0x18036000 /* NorthStar+ Chip Common B SRAB base */ ++ ++/* core codes */ ++#define NODEV_CORE_ID 0x700 /* Invalid coreid */ ++#define CC_CORE_ID 0x800 /* chipcommon core */ ++#define ILINE20_CORE_ID 0x801 /* iline20 core */ ++#define SRAM_CORE_ID 0x802 /* sram core */ ++#define SDRAM_CORE_ID 0x803 /* sdram core */ ++#define PCI_CORE_ID 0x804 /* pci core */ ++#define MIPS_CORE_ID 0x805 /* mips core */ ++#define ENET_CORE_ID 0x806 /* enet mac core */ ++#define CODEC_CORE_ID 0x807 /* v90 codec core */ ++#define USB_CORE_ID 0x808 /* usb 1.1 host/device core */ ++#define ADSL_CORE_ID 0x809 /* ADSL core */ ++#define ILINE100_CORE_ID 0x80a /* iline100 core */ ++#define IPSEC_CORE_ID 0x80b /* ipsec core */ ++#define UTOPIA_CORE_ID 0x80c /* utopia core */ ++#define PCMCIA_CORE_ID 0x80d /* pcmcia core */ ++#define SOCRAM_CORE_ID 0x80e /* internal memory core */ ++#define MEMC_CORE_ID 0x80f /* memc sdram core */ ++#define OFDM_CORE_ID 0x810 /* OFDM phy core */ ++#define EXTIF_CORE_ID 0x811 /* external interface core */ ++#define D11_CORE_ID 0x812 /* 802.11 MAC core */ ++#define APHY_CORE_ID 0x813 /* 802.11a phy core */ ++#define BPHY_CORE_ID 0x814 /* 802.11b phy core */ ++#define GPHY_CORE_ID 0x815 /* 802.11g phy core */ ++#define MIPS33_CORE_ID 0x816 /* mips3302 core */ ++#define USB11H_CORE_ID 0x817 /* usb 1.1 host core */ ++#define USB11D_CORE_ID 0x818 /* usb 1.1 device core */ ++#define USB20H_CORE_ID 0x819 /* usb 2.0 host core */ ++#define USB20D_CORE_ID 0x81a /* usb 2.0 device core */ ++#define SDIOH_CORE_ID 0x81b /* sdio host core */ ++#define ROBO_CORE_ID 0x81c /* roboswitch core */ ++#define ATA100_CORE_ID 0x81d /* parallel ATA core */ ++#define SATAXOR_CORE_ID 0x81e /* serial ATA & XOR DMA core */ ++#define GIGETH_CORE_ID 0x81f /* gigabit ethernet core */ ++#define PCIE_CORE_ID 0x820 /* pci express core */ ++#define NPHY_CORE_ID 0x821 /* 802.11n 2x2 phy core */ ++#define SRAMC_CORE_ID 0x822 /* SRAM controller core */ ++#define MINIMAC_CORE_ID 0x823 /* MINI MAC/phy core */ ++#define ARM11_CORE_ID 0x824 /* ARM 1176 core */ ++#define ARM7S_CORE_ID 0x825 /* ARM7tdmi-s core */ ++#define LPPHY_CORE_ID 0x826 /* 802.11a/b/g phy core */ ++#define PMU_CORE_ID 0x827 /* PMU core */ ++#define SSNPHY_CORE_ID 0x828 /* 802.11n single-stream phy core */ ++#define SDIOD_CORE_ID 0x829 /* SDIO device core */ ++#define ARMCM3_CORE_ID 0x82a /* ARM Cortex M3 core */ ++#define HTPHY_CORE_ID 0x82b /* 802.11n 4x4 phy core */ ++#define MIPS74K_CORE_ID 0x82c /* mips 74k core */ ++#define GMAC_CORE_ID 0x82d /* Gigabit MAC core */ ++#define DMEMC_CORE_ID 0x82e /* DDR1/2 memory controller core */ ++#define PCIERC_CORE_ID 0x82f /* PCIE Root Complex core */ ++#define OCP_CORE_ID 0x830 /* OCP2OCP bridge core */ ++#define SC_CORE_ID 0x831 /* shared common core */ ++#define AHB_CORE_ID 0x832 /* OCP2AHB bridge core */ ++#define SPIH_CORE_ID 0x833 /* SPI host core */ ++#define I2S_CORE_ID 0x834 /* I2S core */ ++#define DMEMS_CORE_ID 0x835 /* SDR/DDR1 memory controller core */ ++#define DEF_SHIM_COMP 0x837 /* SHIM component in ubus/6362 */ ++ ++#define ACPHY_CORE_ID 0x83b /* Dot11 ACPHY */ ++#define PCIE2_CORE_ID 0x83c /* pci express Gen2 core */ ++#define USB30D_CORE_ID 0x83d /* usb 3.0 device core */ ++#define ARMCR4_CORE_ID 0x83e /* ARM CR4 CPU */ ++#define APB_BRIDGE_CORE_ID 0x135 /* APB bridge core ID */ ++#define AXI_CORE_ID 0x301 /* AXI/GPV core ID */ ++#define EROM_CORE_ID 0x366 /* EROM core ID */ ++#define OOB_ROUTER_CORE_ID 0x367 /* OOB router core ID */ ++#define DEF_AI_COMP 0xfff /* Default component, in ai chips it maps all ++ * unused address ranges ++ */ ++ ++#define CC_4706_CORE_ID 0x500 /* chipcommon core */ ++#define NS_PCIEG2_CORE_ID 0x501 /* PCIE Gen 2 core */ ++#define NS_DMA_CORE_ID 0x502 /* DMA core */ ++#define NS_SDIO3_CORE_ID 0x503 /* SDIO3 core */ ++#define NS_USB20_CORE_ID 0x504 /* USB2.0 core */ ++#define NS_USB30_CORE_ID 0x505 /* USB3.0 core */ ++#define NS_A9JTAG_CORE_ID 0x506 /* ARM Cortex A9 JTAG core */ ++#define NS_DDR23_CORE_ID 0x507 /* Denali DDR2/DDR3 memory controller */ ++#define NS_ROM_CORE_ID 0x508 /* ROM core */ ++#define NS_NAND_CORE_ID 0x509 /* NAND flash controller core */ ++#define NS_QSPI_CORE_ID 0x50a /* SPI flash controller core */ ++#define NS_CCB_CORE_ID 0x50b /* ChipcommonB core */ ++#define SOCRAM_4706_CORE_ID 0x50e /* internal memory core */ ++#define NS_SOCRAM_CORE_ID SOCRAM_4706_CORE_ID ++#define ARMCA9_CORE_ID 0x510 /* ARM Cortex A9 core (ihost) */ ++#define NS_IHOST_CORE_ID ARMCA9_CORE_ID /* ARM Cortex A9 core (ihost) */ ++#define GMAC_COMMON_4706_CORE_ID 0x5dc /* Gigabit MAC core */ ++#define GMAC_4706_CORE_ID 0x52d /* Gigabit MAC core */ ++#define AMEMC_CORE_ID 0x52e /* DDR1/2 memory controller core */ ++#define ALTA_CORE_ID 0x534 /* I2S core */ ++#define DDR23_PHY_CORE_ID 0x5dd ++ ++#define SI_PCI1_MEM 0x40000000 /* Host Mode sb2pcitranslation0 (64 MB) */ ++#define SI_PCI1_CFG 0x44000000 /* Host Mode sb2pcitranslation1 (64 MB) */ ++#define SI_PCIE1_DMA_H32 0xc0000000 /* PCIE Client Mode sb2pcitranslation2 ++ * (2 ZettaBytes), high 32 bits ++ */ ++#define CC_4706B0_CORE_REV 0x8000001f /* chipcommon core */ ++#define SOCRAM_4706B0_CORE_REV 0x80000005 /* internal memory core */ ++#define GMAC_4706B0_CORE_REV 0x80000000 /* Gigabit MAC core */ ++ ++/* There are TWO constants on all HND chips: SI_ENUM_BASE above, ++ * and chipcommon being the first core: ++ */ ++#define SI_CC_IDX 0 ++ ++/* SOC Interconnect types (aka chip types) */ ++#define SOCI_SB 0 ++#define SOCI_AI 1 ++#define SOCI_UBUS 2 ++#define SOCI_NS 3 ++ ++/* Common core control flags */ ++#define SICF_BIST_EN 0x8000 ++#define SICF_PME_EN 0x4000 ++#define SICF_CORE_BITS 0x3ffc ++#define SICF_FGC 0x0002 ++#define SICF_CLOCK_EN 0x0001 ++ ++/* Common core status flags */ ++#define SISF_BIST_DONE 0x8000 ++#define SISF_BIST_ERROR 0x4000 ++#define SISF_GATED_CLK 0x2000 ++#define SISF_DMA64 0x1000 ++#define SISF_CORE_BITS 0x0fff ++ ++/* Norstar core status flags */ ++#define SISF_NS_BOOTDEV_MASK 0x0003 /* ROM core */ ++#define SISF_NS_BOOTDEV_NOR 0x0000 /* ROM core */ ++#define SISF_NS_BOOTDEV_NAND 0x0001 /* ROM core */ ++#define SISF_NS_BOOTDEV_ROM 0x0002 /* ROM core */ ++#define SISF_NS_BOOTDEV_OFFLOAD 0x0003 /* ROM core */ ++#define SISF_NS_SKUVEC_MASK 0x000c /* ROM core */ ++ ++/* A register that is common to all cores to ++ * communicate w/PMU regarding clock control. ++ */ ++#define SI_CLK_CTL_ST 0x1e0 /* clock control and status */ ++ ++/* clk_ctl_st register */ ++#define CCS_FORCEALP 0x00000001 /* force ALP request */ ++#define CCS_FORCEHT 0x00000002 /* force HT request */ ++#define CCS_FORCEILP 0x00000004 /* force ILP request */ ++#define CCS_ALPAREQ 0x00000008 /* ALP Avail Request */ ++#define CCS_HTAREQ 0x00000010 /* HT Avail Request */ ++#define CCS_FORCEHWREQOFF 0x00000020 /* Force HW Clock Request Off */ ++#define CCS_HQCLKREQ 0x00000040 /* HQ Clock Required */ ++#define CCS_USBCLKREQ 0x00000100 /* USB Clock Req */ ++#define CCS_ERSRC_REQ_MASK 0x00000700 /* external resource requests */ ++#define CCS_ERSRC_REQ_SHIFT 8 ++#define CCS_ALPAVAIL 0x00010000 /* ALP is available */ ++#define CCS_HTAVAIL 0x00020000 /* HT is available */ ++#define CCS_BP_ON_APL 0x00040000 /* RO: Backplane is running on ALP clock */ ++#define CCS_BP_ON_HT 0x00080000 /* RO: Backplane is running on HT clock */ ++#define CCS_ERSRC_STS_MASK 0x07000000 /* external resource status */ ++#define CCS_ERSRC_STS_SHIFT 24 ++ ++#define CCS0_HTAVAIL 0x00010000 /* HT avail in chipc and pcmcia on 4328a0 */ ++#define CCS0_ALPAVAIL 0x00020000 /* ALP avail in chipc and pcmcia on 4328a0 */ ++ ++/* Not really related to SOC Interconnect, but a couple of software ++ * conventions for the use the flash space: ++ */ ++ ++/* Minumum amount of flash we support */ ++#define FLASH_MIN 0x00020000 /* Minimum flash size */ ++ ++/* A boot/binary may have an embedded block that describes its size */ ++#define BISZ_OFFSET 0x3e0 /* At this offset into the binary */ ++#define BISZ_MAGIC 0x4249535a /* Marked with this value: 'BISZ' */ ++#define BISZ_MAGIC_IDX 0 /* Word 0: magic */ ++#define BISZ_TXTST_IDX 1 /* 1: text start */ ++#define BISZ_TXTEND_IDX 2 /* 2: text end */ ++#define BISZ_DATAST_IDX 3 /* 3: data start */ ++#define BISZ_DATAEND_IDX 4 /* 4: data end */ ++#define BISZ_BSSST_IDX 5 /* 5: bss start */ ++#define BISZ_BSSEND_IDX 6 /* 6: bss end */ ++#define BISZ_SIZE 7 /* descriptor size in 32-bit integers */ ++ ++#endif /* _HNDSOC_H */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/hndtcam.h b/drivers/net/ethernet/broadcom/gmac/src/include/hndtcam.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/hndtcam.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/hndtcam.h 2017-11-09 17:53:43.966304000 +0800 +@@ -0,0 +1,95 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * HND SOCRAM TCAM software interface. ++ * ++ * $Id: hndtcam.h 317281 2012-02-27 11:23:27Z $ ++ */ ++#ifndef _hndtcam_h_ ++#define _hndtcam_h_ ++ ++/* ++ * 0 - 1 ++ * 1 - 2 Consecutive locations are patched ++ * 2 - 4 Consecutive locations are patched ++ * 3 - 8 Consecutive locations are patched ++ * 4 - 16 Consecutive locations are patched ++ * Define default to patch 2 locations ++ */ ++ ++#ifdef PATCHCOUNT ++#define SRPC_PATCHCOUNT PATCHCOUNT ++#else ++#define PATCHCOUNT 0 ++#define SRPC_PATCHCOUNT PATCHCOUNT ++#endif ++ ++#if defined(__ARM_ARCH_7R__) ++#ifndef PATCHCOUNT ++#define PATCHCOUNT 1 ++#endif ++#define ARMCR4_TCAMPATCHCOUNT PATCHCOUNT ++#define ARMCR4_TCAMADDR_MASK (~((1 << (ARMCR4_TCAMPATCHCOUNT + 2))-1)) ++#define ARMCR4_PATCHNLOC (1 << ARMCR4_TCAMPATCHCOUNT) ++#endif /* defined(__ARM_ARCH_7R__) */ ++ ++/* N Consecutive location to patch */ ++#define SRPC_PATCHNLOC (1 << (SRPC_PATCHCOUNT)) ++ ++#define PATCHHDR(_p) __attribute__ ((__section__ (".patchhdr."#_p))) _p ++#define PATCHENTRY(_p) __attribute__ ((__section__ (".patchentry."#_p))) _p ++ ++#if defined(__ARM_ARCH_7R__) ++typedef struct { ++ uint32 data[ARMCR4_PATCHNLOC]; ++} patch_entry_t; ++#else ++typedef struct { ++ uint32 data[SRPC_PATCHNLOC]; ++} patch_entry_t; ++#endif ++ ++typedef struct { ++ void *addr; /* patch address */ ++ uint32 len; /* bytes to patch in entry */ ++ patch_entry_t *entry; /* patch entry data */ ++} patch_hdr_t; ++ ++/* patch values and address structure */ ++typedef struct patchaddrvalue { ++ uint32 addr; ++ uint32 value; ++} patchaddrvalue_t; ++ ++extern void *socram_regs; ++extern uint32 socram_rev; ++ ++extern void *arm_regs; ++ ++extern void hnd_patch_init(void *srp); ++extern void hnd_tcam_write(void *srp, uint16 idx, uint32 data); ++extern void hnd_tcam_read(void *srp, uint16 idx, uint32 *content); ++void * hnd_tcam_init(void *srp, int no_addrs); ++extern void hnd_tcam_disablepatch(void *srp); ++extern void hnd_tcam_enablepatch(void *srp); ++#ifdef CONFIG_XIP ++extern void hnd_tcam_bootloader_load(void *srp, char *pvars); ++#else ++extern void hnd_tcam_load(void *srp, const patchaddrvalue_t *patchtbl); ++#endif /* CONFIG_XIP */ ++extern void BCMATTACHFN(hnd_tcam_load_default)(void); ++extern void hnd_tcam_reclaim(void); ++ ++#endif /* _hndtcam_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/linux_osl.h b/drivers/net/ethernet/broadcom/gmac/src/include/linux_osl.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/linux_osl.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/linux_osl.h 2017-11-09 17:53:43.968293000 +0800 +@@ -0,0 +1,737 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Linux OS Independent Layer ++ * ++ * $Id: linux_osl.h 329351 2012-04-25 01:48:39Z $ ++ */ ++ ++#ifndef _linux_osl_h_ ++#define _linux_osl_h_ ++ ++#include ++ ++/* Linux Kernel: File Operations: start */ ++extern void * osl_os_open_image(char * filename); ++extern int osl_os_get_image_block(char * buf, int len, void * image); ++extern void osl_os_close_image(void * image); ++extern int osl_os_image_size(void *image); ++/* Linux Kernel: File Operations: end */ ++ ++#ifdef BCMDRIVER ++ ++/* OSL initialization */ ++extern osl_t *osl_attach(void *pdev, uint bustype, bool pkttag); ++extern void osl_detach(osl_t *osh); ++ ++/* Global ASSERT type */ ++extern uint32 g_assert_type; ++ ++/* ASSERT */ ++ #ifdef __GNUC__ ++ #define GCC_VERSION \ ++ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) ++ #if GCC_VERSION > 30100 ++ #define ASSERT(exp) do {} while (0) ++ #else ++ /* ASSERT could cause segmentation fault on GCC3.1, use empty instead */ ++ #define ASSERT(exp) ++ #endif /* GCC_VERSION > 30100 */ ++ #endif /* __GNUC__ */ ++ ++/* microsecond delay */ ++#define OSL_DELAY(usec) osl_delay(usec) ++extern void osl_delay(uint usec); ++ ++#define OSL_PCMCIA_READ_ATTR(osh, offset, buf, size) \ ++ osl_pcmcia_read_attr((osh), (offset), (buf), (size)) ++#define OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size) \ ++ osl_pcmcia_write_attr((osh), (offset), (buf), (size)) ++extern void osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size); ++extern void osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size); ++ ++/* PCI configuration space access macros */ ++#define OSL_PCI_READ_CONFIG(osh, offset, size) \ ++ osl_pci_read_config((osh), (offset), (size)) ++#define OSL_PCI_WRITE_CONFIG(osh, offset, size, val) \ ++ osl_pci_write_config((osh), (offset), (size), (val)) ++extern uint32 osl_pci_read_config(osl_t *osh, uint offset, uint size); ++extern void osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val); ++ ++/* PCI device bus # and slot # */ ++#define OSL_PCI_BUS(osh) osl_pci_bus(osh) ++#define OSL_PCI_SLOT(osh) osl_pci_slot(osh) ++extern uint osl_pci_bus(osl_t *osh); ++extern uint osl_pci_slot(osl_t *osh); ++extern struct pci_dev *osl_pci_device(osl_t *osh); ++ ++/* Pkttag flag should be part of public information */ ++typedef struct { ++ bool pkttag; ++ bool mmbus; /* Bus supports memory-mapped register accesses */ ++ pktfree_cb_fn_t tx_fn; /* Callback function for PKTFREE */ ++ void *tx_ctx; /* Context to the callback function */ ++#ifdef OSLREGOPS ++ osl_rreg_fn_t rreg_fn; /* Read Register function */ ++ osl_wreg_fn_t wreg_fn; /* Write Register function */ ++ void *reg_ctx; /* Context to the reg callback functions */ ++#else ++ void *unused[3]; ++#endif ++} osl_pubinfo_t; ++ ++#define PKTFREESETCB(osh, _tx_fn, _tx_ctx) \ ++ do { \ ++ ((osl_pubinfo_t*)osh)->tx_fn = _tx_fn; \ ++ ((osl_pubinfo_t*)osh)->tx_ctx = _tx_ctx; \ ++ } while (0) ++ ++#ifdef OSLREGOPS ++#define REGOPSSET(osh, rreg, wreg, ctx) \ ++ do { \ ++ ((osl_pubinfo_t*)osh)->rreg_fn = rreg; \ ++ ((osl_pubinfo_t*)osh)->wreg_fn = wreg; \ ++ ((osl_pubinfo_t*)osh)->reg_ctx = ctx; \ ++ } while (0) ++#endif /* OSLREGOPS */ ++ ++/* host/bus architecture-specific byte swap */ ++// #define BUS_SWAP32(v) (v) /* JIRA:LINUXDEV-16 */ ++#ifdef IL_BIGENDIAN ++#define BUS_SWAP32(v) bcmswap32(v) ++#else ++#define BUS_SWAP32(v) (v) ++#endif /* IL_BIGENDIAN */ ++ ++ #define MALLOC(osh, size) osl_malloc((osh), (size)) ++ #define MFREE(osh, addr, size) osl_mfree((osh), (addr), (size)) ++ #define MALLOCED(osh) osl_malloced((osh)) ++ extern void *osl_malloc(osl_t *osh, uint size); ++ extern void osl_mfree(osl_t *osh, void *addr, uint size); ++ extern uint osl_malloced(osl_t *osh); ++ ++#define NATIVE_MALLOC(osh, size) kmalloc(size, GFP_ATOMIC) ++#define NATIVE_MFREE(osh, addr, size) kfree(addr) ++#ifdef USBAP ++#include ++#define VMALLOC(osh, size) vmalloc(size) ++#define VFREE(osh, addr, size) vfree(addr) ++#endif /* USBAP */ ++ ++#define MALLOC_FAILED(osh) osl_malloc_failed((osh)) ++extern uint osl_malloc_failed(osl_t *osh); ++ ++/* allocate/free shared (dma-able) consistent memory */ ++#define DMA_CONSISTENT_ALIGN osl_dma_consistent_align() ++#define DMA_ALLOC_CONSISTENT(osh, size, align, tot, pap, dmah) \ ++ osl_dma_alloc_consistent((osh), (size), (align), (tot), (pap)) ++#define DMA_FREE_CONSISTENT(osh, va, size, pa, dmah) \ ++ osl_dma_free_consistent((osh), (void*)(va), (size), (pa)) ++extern uint osl_dma_consistent_align(void); ++extern void *osl_dma_alloc_consistent(osl_t *osh, uint size, uint16 align, uint *tot, ulong *pap); ++extern void osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa); ++ ++/* map/unmap direction */ ++#define DMA_TX 1 /* TX direction for DMA */ ++#define DMA_RX 2 /* RX direction for DMA */ ++ ++/* map/unmap shared (dma-able) memory */ ++#define DMA_UNMAP(osh, pa, size, direction, p, dmah) \ ++ osl_dma_unmap((osh), (pa), (size), (direction)) ++extern uint osl_dma_map(osl_t *osh, void *va, uint size, int direction, void *p, hnddma_seg_map_t *dmah); ++extern void osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction); ++ ++/* API for DMA addressing capability */ ++#define OSL_DMADDRWIDTH(osh, addrwidth) do {} while (0) ++ ++#define SELECT_BUS_WRITE(osh, mmap_op, bus_op) mmap_op ++#define SELECT_BUS_READ(osh, mmap_op, bus_op) mmap_op ++ ++#define OSL_ERROR(bcmerror) osl_error(bcmerror) ++extern int osl_error(int bcmerror); ++ ++/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */ ++#define PKTBUFSZ 2048 /* largest reasonable packet buffer, driver uses for ethernet MTU */ ++ ++/* ++ * BINOSL selects the slightly slower function-call-based binary compatible osl. ++ * Macros expand to calls to functions defined in linux_osl.c . ++ */ ++#ifndef BINOSL ++#include /* use current 2.4.x calling conventions */ ++#include /* for vsn/printf's */ ++#include /* for mem*, str* */ ++ ++#define OSL_SYSUPTIME() ((uint32)jiffies * (1000 / HZ)) ++#define printf(fmt, args...) printk(fmt , ## args) ++#include /* for vsn/printf's */ ++#include /* for mem*, str* */ ++/* bcopy's: Linux kernel doesn't provide these (anymore) */ ++#define bcopy(src, dst, len) memcpy((dst), (src), (len)) ++#define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) ++#define bzero(b, len) memset((b), '\0', (len)) ++ ++/* register access macros */ ++#if defined(OSLREGOPS) ++#define R_REG(osh, r) (\ ++ sizeof(*(r)) == sizeof(uint8) ? osl_readb((osh), (volatile uint8*)(r)) : \ ++ sizeof(*(r)) == sizeof(uint16) ? osl_readw((osh), (volatile uint16*)(r)) : \ ++ osl_readl((osh), (volatile uint32*)(r)) \ ++) ++#define W_REG(osh, r, v) do { \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): osl_writeb((osh), (volatile uint8*)(r), (uint8)(v)); break; \ ++ case sizeof(uint16): osl_writew((osh), (volatile uint16*)(r), (uint16)(v)); break; \ ++ case sizeof(uint32): osl_writel((osh), (volatile uint32*)(r), (uint32)(v)); break; \ ++ } \ ++} while (0) ++ ++extern uint8 osl_readb(osl_t *osh, volatile uint8 *r); ++extern uint16 osl_readw(osl_t *osh, volatile uint16 *r); ++extern uint32 osl_readl(osl_t *osh, volatile uint32 *r); ++extern void osl_writeb(osl_t *osh, volatile uint8 *r, uint8 v); ++extern void osl_writew(osl_t *osh, volatile uint16 *r, uint16 v); ++extern void osl_writel(osl_t *osh, volatile uint32 *r, uint32 v); ++#else /* OSLREGOPS */ ++ ++#ifndef IL_BIGENDIAN ++#ifndef __mips__ ++#define R_REG(osh, r) (\ ++ SELECT_BUS_READ(osh, \ ++ ({ \ ++ __typeof(*(r)) __osl_v; \ ++ BCM_REFERENCE(osh); \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): __osl_v = \ ++ readb((volatile uint8*)(r)); break; \ ++ case sizeof(uint16): __osl_v = \ ++ readw((volatile uint16*)(r)); break; \ ++ case sizeof(uint32): __osl_v = \ ++ readl((volatile uint32*)(r)); break; \ ++ } \ ++ __osl_v; \ ++ }), \ ++ OSL_READ_REG(osh, r)) \ ++) ++#else /* __mips__ */ ++#define R_REG(osh, r) (\ ++ SELECT_BUS_READ(osh, \ ++ ({ \ ++ __typeof(*(r)) __osl_v; \ ++ BCM_REFERENCE(osh); \ ++ __asm__ __volatile__("sync"); \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): __osl_v = \ ++ readb((volatile uint8*)(r)); break; \ ++ case sizeof(uint16): __osl_v = \ ++ readw((volatile uint16*)(r)); break; \ ++ case sizeof(uint32): __osl_v = \ ++ readl((volatile uint32*)(r)); break; \ ++ } \ ++ __asm__ __volatile__("sync"); \ ++ __osl_v; \ ++ }), \ ++ ({ \ ++ __typeof(*(r)) __osl_v; \ ++ __asm__ __volatile__("sync"); \ ++ __osl_v = OSL_READ_REG(osh, r); \ ++ __asm__ __volatile__("sync"); \ ++ __osl_v; \ ++ })) \ ++) ++#endif /* __mips__ */ ++ ++#define W_REG(osh, r, v) do { \ ++ BCM_REFERENCE(osh); \ ++ SELECT_BUS_WRITE(osh, \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)(r)); break; \ ++ case sizeof(uint16): writew((uint16)(v), (volatile uint16*)(r)); break; \ ++ case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \ ++ }, \ ++ (OSL_WRITE_REG(osh, r, v))); \ ++ } while (0) ++#else /* IL_BIGENDIAN */ ++#define R_REG(osh, r) (\ ++ SELECT_BUS_READ(osh, \ ++ ({ \ ++ __typeof(*(r)) __osl_v; \ ++ BCM_REFERENCE(osh); \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): __osl_v = \ ++ readb((volatile uint8*)((uintptr)(r)^3)); break; \ ++ case sizeof(uint16): __osl_v = \ ++ readw((volatile uint16*)((uintptr)(r)^2)); break; \ ++ case sizeof(uint32): __osl_v = \ ++ readl((volatile uint32*)(r)); break; \ ++ } \ ++ __osl_v; \ ++ }), \ ++ OSL_READ_REG(osh, r)) \ ++) ++#define W_REG(osh, r, v) do { \ ++ BCM_REFERENCE(osh); \ ++ SELECT_BUS_WRITE(osh, \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): writeb((uint8)(v), \ ++ (volatile uint8*)((uintptr)(r)^3)); break; \ ++ case sizeof(uint16): writew((uint16)(v), \ ++ (volatile uint16*)((uintptr)(r)^2)); break; \ ++ case sizeof(uint32): writel((uint32)(v), \ ++ (volatile uint32*)(r)); break; \ ++ }, \ ++ (OSL_WRITE_REG(osh, r, v))); \ ++ } while (0) ++#endif /* IL_BIGENDIAN */ ++#endif /* OSLREGOPS */ ++ ++#define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v)) ++#define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v)) ++ ++/* bcopy, bcmp, and bzero functions */ ++#define bcopy(src, dst, len) memcpy((dst), (src), (len)) ++#define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) ++#define bzero(b, len) memset((b), '\0', (len)) ++ ++/* uncached/cached virtual address */ ++#ifdef __mips__ ++#include ++#define OSL_UNCACHED(va) ((void *)KSEG1ADDR((va))) ++#define OSL_CACHED(va) ((void *)KSEG0ADDR((va))) ++#else ++#define OSL_UNCACHED(va) ((void *)va) ++#define OSL_CACHED(va) ((void *)va) ++ ++/* ARM NorthStar */ ++#define OSL_CACHE_FLUSH(va, len) ++ ++#endif /* mips */ ++ ++#ifdef __mips__ ++#define OSL_PREF_RANGE_LD(va, sz) prefetch_range_PREF_LOAD_RETAINED(va, sz) ++#define OSL_PREF_RANGE_ST(va, sz) prefetch_range_PREF_STORE_RETAINED(va, sz) ++#else /* __mips__ */ ++#define OSL_PREF_RANGE_LD(va, sz) ++#define OSL_PREF_RANGE_ST(va, sz) ++#endif /* __mips__ */ ++ ++/* get processor cycle count */ ++#if defined(mips) ++#define OSL_GETCYCLES(x) ((x) = read_c0_count() * 2) ++#elif defined(__i386__) ++#define OSL_GETCYCLES(x) rdtscl((x)) ++#else ++#define OSL_GETCYCLES(x) ((x) = 0) ++#endif /* defined(mips) */ ++ ++/* dereference an address that may cause a bus exception */ ++#ifdef mips ++#if defined(MODULE) && (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 17)) ++#define BUSPROBE(val, addr) panic("get_dbe() will not fixup a bus exception when compiled into"\ ++ " a module") ++#else ++#define BUSPROBE(val, addr) get_dbe((val), (addr)) ++#include ++#endif /* defined(MODULE) && (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 17)) */ ++#else ++#define BUSPROBE(val, addr) ({ (val) = R_REG(NULL, (addr)); 0; }) ++#endif /* mips */ ++ ++/* map/unmap physical to virtual I/O */ ++#if !defined(CONFIG_MMC_MSM7X00A) ++#define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), (unsigned long)(size)) ++#else ++#define REG_MAP(pa, size) (void *)(0) ++#endif /* !defined(CONFIG_MMC_MSM7X00A */ ++#define REG_UNMAP(va) iounmap((va)) ++ ++/* shared (dma-able) memory access macros */ ++#define R_SM(r) *(r) ++#define W_SM(r, v) (*(r) = (v)) ++#define BZERO_SM(r, len) memset((r), '\0', (len)) ++ ++/* Because the non BINOSL implemenation of the PKT OSL routines are macros (for ++ * performance reasons), we need the Linux headers. ++ */ ++#include /* use current 2.4.x calling conventions */ ++ ++/* packet primitives */ ++#define PKTGET(osh, len, send) osl_pktget((osh), (len)) ++#define PKTDUP(osh, skb) osl_pktdup((osh), (skb)) ++#define PKTLIST_DUMP(osh, buf) ++#define PKTDBG_TRACE(osh, pkt, bit) ++#define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb), (send)) ++#ifdef DHD_USE_STATIC_BUF ++#define PKTGET_STATIC(osh, len, send) osl_pktget_static((osh), (len)) ++#define PKTFREE_STATIC(osh, skb, send) osl_pktfree_static((osh), (skb), (send)) ++#endif /* DHD_USE_STATIC_BUF */ ++#define PKTDATA(osh, skb) (((struct sk_buff*)(skb))->data) ++#define PKTLEN(osh, skb) (((struct sk_buff*)(skb))->len) ++#define PKTHEADROOM(osh, skb) (PKTDATA(osh, skb)-(((struct sk_buff*)(skb))->head)) ++#define PKTTAILROOM(osh, skb) ((((struct sk_buff*)(skb))->end)-(((struct sk_buff*)(skb))->tail)) ++#define PKTNEXT(osh, skb) (((struct sk_buff*)(skb))->next) ++#define PKTSETNEXT(osh, skb, x) (((struct sk_buff*)(skb))->next = (struct sk_buff*)(x)) ++#define PKTSETLEN(osh, skb, len) __pskb_trim((struct sk_buff*)(skb), (len)) ++#define PKTPUSH(osh, skb, bytes) skb_push((struct sk_buff*)(skb), (bytes)) ++#define PKTPULL(osh, skb, bytes) skb_pull((struct sk_buff*)(skb), (bytes)) ++#define PKTTAG(skb) ((void*)(((struct sk_buff*)(skb))->cb)) ++#define PKTSETPOOL(osh, skb, x, y) do {} while (0) ++#define PKTPOOL(osh, skb) FALSE ++#define PKTSHRINK(osh, m) (m) ++ ++#define FASTBUF (1 << 16) ++#define CTFBUF (1 << 17) ++#define PKTSETFAST(osh, skb) ((((struct sk_buff*)(skb))->mac_len) |= FASTBUF) ++#define PKTCLRFAST(osh, skb) ((((struct sk_buff*)(skb))->mac_len) &= (~FASTBUF)) ++#define PKTSETCTF(osh, skb) ((((struct sk_buff*)(skb))->mac_len) |= CTFBUF) ++#define PKTCLRCTF(osh, skb) ((((struct sk_buff*)(skb))->mac_len) &= (~CTFBUF)) ++#define PKTISFAST(osh, skb) ((((struct sk_buff*)(skb))->mac_len) & FASTBUF) ++#define PKTISCTF(osh, skb) ((((struct sk_buff*)(skb))->mac_len) & CTFBUF) ++#define PKTFAST(osh, skb) (((struct sk_buff*)(skb))->mac_len) ++ ++#define PKTSETSKIPCT(osh, skb) ++#define PKTCLRSKIPCT(osh, skb) ++#define PKTSKIPCT(osh, skb) ++#define PKTCLRCHAINED(osh, skb) ++#define PKTSETCHAINED(osh, skb) ++#define CTF_MARK(m) 0 ++ ++#ifdef BCMFA ++#ifdef BCMFA_HW_HASH ++#define PKTSETFAHIDX(skb, idx) (((struct sk_buff*)(skb))->napt_idx = idx) ++#else ++#define PKTSETFAHIDX(skb, idx) ++#endif /* BCMFA_SW_HASH */ ++#define PKTGETFAHIDX(skb) (((struct sk_buff*)(skb))->napt_idx) ++#define PKTSETFADEV(skb, imp) (((struct sk_buff*)(skb))->dev = imp) ++#define PKTSETRXDEV(skb) (((struct sk_buff*)(skb))->rxdev = ((struct sk_buff*)(skb))->dev) ++ ++#define AUX_TCP_FIN_RST (1 << 0) ++#define AUX_FREED (1 << 1) ++#define PKTSETFAAUX(skb) (((struct sk_buff*)(skb))->napt_flags |= AUX_TCP_FIN_RST) ++#define PKTCLRFAAUX(skb) (((struct sk_buff*)(skb))->napt_flags &= (~AUX_TCP_FIN_RST)) ++#define PKTISFAAUX(skb) (((struct sk_buff*)(skb))->napt_flags & AUX_TCP_FIN_RST) ++#define PKTSETFAFREED(skb) (((struct sk_buff*)(skb))->napt_flags |= AUX_FREED) ++#define PKTCLRFAFREED(skb) (((struct sk_buff*)(skb))->napt_flags &= (~AUX_FREED)) ++#define PKTISFAFREED(skb) (((struct sk_buff*)(skb))->napt_flags & AUX_FREED) ++#define PKTISFABRIDGED(skb) PKTISFAAUX(skb) ++#else ++#define PKTISFAAUX(skb) (FALSE) ++#define PKTISFABRIDGED(skb) (FALSE) ++#define PKTISFAFREED(skb) (FALSE) ++ ++#define PKTCLRFAAUX(skb) ++#define PKTSETFAFREED(skb) ++#define PKTCLRFAFREED(skb) ++#endif /* BCMFA */ ++ ++extern void osl_pktfree(osl_t *osh, void *skb, bool send); ++extern void *osl_pktget_static(osl_t *osh, uint len); ++extern void osl_pktfree_static(osl_t *osh, void *skb, bool send); ++ ++extern void *osl_pkt_frmnative(osl_t *osh, void *skb); ++extern void *osl_pktget(osl_t *osh, uint len); ++extern void *osl_pktdup(osl_t *osh, void *skb); ++extern struct sk_buff *osl_pkt_tonative(osl_t *osh, void *pkt); ++#define PKTFRMNATIVE(osh, skb) osl_pkt_frmnative(((osl_t *)osh), (struct sk_buff*)(skb)) ++#define PKTTONATIVE(osh, pkt) osl_pkt_tonative((osl_t *)(osh), (pkt)) ++ ++#define PKTLINK(skb) (((struct sk_buff*)(skb))->prev) ++#define PKTSETLINK(skb, x) (((struct sk_buff*)(skb))->prev = (struct sk_buff*)(x)) ++#define PKTPRIO(skb) (((struct sk_buff*)(skb))->priority) ++#define PKTSETPRIO(skb, x) (((struct sk_buff*)(skb))->priority = (x)) ++#define PKTSUMNEEDED(skb) (((struct sk_buff*)(skb))->ip_summed == CHECKSUM_HW) ++#define PKTSETSUMGOOD(skb, x) (((struct sk_buff*)(skb))->ip_summed = \ ++ ((x) ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE)) ++/* PKTSETSUMNEEDED and PKTSUMGOOD are not possible because skb->ip_summed is overloaded */ ++#define PKTSHARED(skb) (((struct sk_buff*)(skb))->cloned) ++ ++#ifdef CONFIG_NF_CONNTRACK_MARK ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) ++#define PKTMARK(p) (((struct sk_buff *)(p))->mark) ++#define PKTSETMARK(p, m) ((struct sk_buff *)(p))->mark = (m) ++#else /* !2.6.0 */ ++#define PKTMARK(p) (((struct sk_buff *)(p))->nfmark) ++#define PKTSETMARK(p, m) ((struct sk_buff *)(p))->nfmark = (m) ++#endif /* 2.6.0 */ ++#else /* CONFIG_NF_CONNTRACK_MARK */ ++#define PKTMARK(p) 0 ++#define PKTSETMARK(p, m) ++#endif /* CONFIG_NF_CONNTRACK_MARK */ ++ ++#else /* BINOSL */ ++ ++/* Where to get the declarations for mem, str, printf, bcopy's? Two basic approaches. ++ * ++ * First, use the Linux header files and the C standard library replacmenent versions ++ * built-in to the kernel. Use this approach when compiling non hybrid code or compling ++ * the OS port files. The second approach is to use our own defines/prototypes and ++ * functions we have provided in the Linux OSL, i.e. linux_osl.c. Use this approach when ++ * compiling the files that make up the hybrid binary. We are ensuring we ++ * don't directly link to the kernel replacement routines from the hybrid binary. ++ * ++ * NOTE: The issue we are trying to avoid is any questioning of whether the ++ * hybrid binary is derived from Linux. The wireless common code (wlc) is designed ++ * to be OS independent through the use of the OSL API and thus the hybrid binary doesn't ++ * derive from the Linux kernel at all. But since we defined our OSL API to include ++ * a small collection of standard C library routines and these routines are provided in ++ * the kernel we want to avoid even the appearance of deriving at all even though clearly ++ * usage of a C standard library API doesn't represent a derivation from Linux. Lastly ++ * note at the time of this checkin 4 references to memcpy/memset could not be eliminated ++ * from the binary because they are created internally by GCC as part of things like ++ * structure assignment. I don't think the compiler should be doing this but there is ++ * no options to disable it on Intel architectures (there is for MIPS so somebody must ++ * agree with me). I may be able to even remove these references eventually with ++ * a GNU binutil such as objcopy via a symbol rename (i.e. memcpy to osl_memcpy). ++ */ ++#if !defined(LINUX_HYBRID) || defined(LINUX_PORT) ++ #define printf(fmt, args...) printk(fmt , ## args) ++ #include /* for vsn/printf's */ ++ #include /* for mem*, str* */ ++ /* bcopy's: Linux kernel doesn't provide these (anymore) */ ++ #define bcopy(src, dst, len) memcpy((dst), (src), (len)) ++ #define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) ++ #define bzero(b, len) memset((b), '\0', (len)) ++ ++ /* These are provided only because when compiling linux_osl.c there ++ * must be an explicit prototype (separate from the definition) because ++ * we are compiling with GCC option -Wstrict-prototypes. Conversely ++ * these could be placed directly in linux_osl.c. ++ */ ++ extern int osl_printf(const char *format, ...); ++ extern int osl_sprintf(char *buf, const char *format, ...); ++ extern int osl_snprintf(char *buf, size_t n, const char *format, ...); ++ extern int osl_vsprintf(char *buf, const char *format, va_list ap); ++ extern int osl_vsnprintf(char *buf, size_t n, const char *format, va_list ap); ++ extern int osl_strcmp(const char *s1, const char *s2); ++ extern int osl_strncmp(const char *s1, const char *s2, uint n); ++ extern int osl_strlen(const char *s); ++ extern char* osl_strcpy(char *d, const char *s); ++ extern char* osl_strncpy(char *d, const char *s, uint n); ++ extern char* osl_strchr(const char *s, int c); ++ extern char* osl_strrchr(const char *s, int c); ++ extern void *osl_memset(void *d, int c, size_t n); ++ extern void *osl_memcpy(void *d, const void *s, size_t n); ++ extern void *osl_memmove(void *d, const void *s, size_t n); ++ extern int osl_memcmp(const void *s1, const void *s2, size_t n); ++#else ++ ++ /* In the below defines we undefine the macro first in case it is ++ * defined. This shouldn't happen because we are not using Linux ++ * header files but because our Linux 2.4 make includes modversions.h ++ * through a GCC -include compile option, they get defined to point ++ * at the appropriate versioned symbol name. Note this doesn't ++ * happen with our Linux 2.6 makes. ++ */ ++ ++ /* *printf functions */ ++ #include /* va_list needed for v*printf */ ++ #include /* size_t needed for *nprintf */ ++ #undef printf ++ #undef sprintf ++ #undef snprintf ++ #undef vsprintf ++ #undef vsnprintf ++ #define printf(fmt, args...) osl_printf((fmt) , ## args) ++ #define sprintf(buf, fmt, args...) osl_sprintf((buf), (fmt) , ## args) ++ #define snprintf(buf, n, fmt, args...) osl_snprintf((buf), (n), (fmt) , ## args) ++ #define vsprintf(buf, fmt, ap) osl_vsprintf((buf), (fmt), (ap)) ++ #define vsnprintf(buf, n, fmt, ap) osl_vsnprintf((buf), (n), (fmt), (ap)) ++ extern int osl_printf(const char *format, ...); ++ extern int osl_sprintf(char *buf, const char *format, ...); ++ extern int osl_snprintf(char *buf, size_t n, const char *format, ...); ++ extern int osl_vsprintf(char *buf, const char *format, va_list ap); ++ extern int osl_vsnprintf(char *buf, size_t n, const char *format, va_list ap); ++ ++ /* str* functions */ ++ #undef strcmp ++ #undef strncmp ++ #undef strlen ++ #undef strcpy ++ #undef strncpy ++ #undef strchr ++ #undef strrchr ++ #define strcmp(s1, s2) osl_strcmp((s1), (s2)) ++ #define strncmp(s1, s2, n) osl_strncmp((s1), (s2), (n)) ++ #define strlen(s) osl_strlen((s)) ++ #define strcpy(d, s) osl_strcpy((d), (s)) ++ #define strncpy(d, s, n) osl_strncpy((d), (s), (n)) ++ #define strchr(s, c) osl_strchr((s), (c)) ++ #define strrchr(s, c) osl_strrchr((s), (c)) ++ extern int osl_strcmp(const char *s1, const char *s2); ++ extern int osl_strncmp(const char *s1, const char *s2, uint n); ++ extern int osl_strlen(const char *s); ++ extern char* osl_strcpy(char *d, const char *s); ++ extern char* osl_strncpy(char *d, const char *s, uint n); ++ extern char* osl_strchr(const char *s, int c); ++ extern char* osl_strrchr(const char *s, int c); ++ ++ /* mem* functions */ ++ #undef memset ++ #undef memcpy ++ #undef memcmp ++ #define memset(d, c, n) osl_memset((d), (c), (n)) ++ #define memcpy(d, s, n) osl_memcpy((d), (s), (n)) ++ #define memmove(d, s, n) osl_memmove((d), (s), (n)) ++ #define memcmp(s1, s2, n) osl_memcmp((s1), (s2), (n)) ++ extern void *osl_memset(void *d, int c, size_t n); ++ extern void *osl_memcpy(void *d, const void *s, size_t n); ++ extern void *osl_memmove(void *d, const void *s, size_t n); ++ extern int osl_memcmp(const void *s1, const void *s2, size_t n); ++ ++ /* bcopy, bcmp, and bzero functions */ ++ #undef bcopy ++ #undef bcmp ++ #undef bzero ++ #define bcopy(src, dst, len) osl_memcpy((dst), (src), (len)) ++ #define bcmp(b1, b2, len) osl_memcmp((b1), (b2), (len)) ++ #define bzero(b, len) osl_memset((b), '\0', (len)) ++#endif /* !defined(LINUX_HYBRID) || defined(LINUX_PORT) */ ++ ++/* register access macros */ ++#define R_REG(osh, r) (\ ++ sizeof(*(r)) == sizeof(uint8) ? osl_readb((volatile uint8*)(r)) : \ ++ sizeof(*(r)) == sizeof(uint16) ? osl_readw((volatile uint16*)(r)) : \ ++ osl_readl((volatile uint32*)(r)) \ ++) ++#define W_REG(osh, r, v) do { \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): osl_writeb((uint8)(v), (volatile uint8*)(r)); break; \ ++ case sizeof(uint16): osl_writew((uint16)(v), (volatile uint16*)(r)); break; \ ++ case sizeof(uint32): osl_writel((uint32)(v), (volatile uint32*)(r)); break; \ ++ } \ ++} while (0) ++ ++#define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v)) ++#define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v)) ++extern uint8 osl_readb(volatile uint8 *r); ++extern uint16 osl_readw(volatile uint16 *r); ++extern uint32 osl_readl(volatile uint32 *r); ++extern void osl_writeb(uint8 v, volatile uint8 *r); ++extern void osl_writew(uint16 v, volatile uint16 *r); ++extern void osl_writel(uint32 v, volatile uint32 *r); ++ ++/* system up time in ms */ ++#define OSL_SYSUPTIME() osl_sysuptime() ++extern uint32 osl_sysuptime(void); ++ ++/* uncached/cached virtual address */ ++#define OSL_UNCACHED(va) osl_uncached((va)) ++extern void *osl_uncached(void *va); ++#define OSL_CACHED(va) osl_cached((va)) ++extern void *osl_cached(void *va); ++ ++#define OSL_PREF_RANGE_LD(va, sz) ++#define OSL_PREF_RANGE_ST(va, sz) ++ ++/* get processor cycle count */ ++#define OSL_GETCYCLES(x) ((x) = osl_getcycles()) ++extern uint osl_getcycles(void); ++ ++/* dereference an address that may target abort */ ++#define BUSPROBE(val, addr) osl_busprobe(&(val), (addr)) ++extern int osl_busprobe(uint32 *val, uint32 addr); ++ ++/* map/unmap physical to virtual */ ++#define REG_MAP(pa, size) osl_reg_map((pa), (size)) ++#define REG_UNMAP(va) osl_reg_unmap((va)) ++extern void *osl_reg_map(uint32 pa, uint size); ++extern void osl_reg_unmap(void *va); ++ ++/* shared (dma-able) memory access macros */ ++#define R_SM(r) *(r) ++#define W_SM(r, v) (*(r) = (v)) ++#define BZERO_SM(r, len) bzero((r), (len)) ++ ++/* packet primitives */ ++#define PKTGET(osh, len, send) osl_pktget((osh), (len)) ++#define PKTDUP(osh, skb) osl_pktdup((osh), (skb)) ++#define PKTFRMNATIVE(osh, skb) osl_pkt_frmnative((osh), (skb)) ++#define PKTLIST_DUMP(osh, buf) ++#define PKTDBG_TRACE(osh, pkt, bit) ++#define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb), (send)) ++#define PKTDATA(osh, skb) osl_pktdata((osh), (skb)) ++#define PKTLEN(osh, skb) osl_pktlen((osh), (skb)) ++#define PKTHEADROOM(osh, skb) osl_pktheadroom((osh), (skb)) ++#define PKTTAILROOM(osh, skb) osl_pkttailroom((osh), (skb)) ++#define PKTNEXT(osh, skb) osl_pktnext((osh), (skb)) ++#define PKTSETNEXT(osh, skb, x) osl_pktsetnext((skb), (x)) ++#define PKTSETLEN(osh, skb, len) osl_pktsetlen((osh), (skb), (len)) ++#define PKTPUSH(osh, skb, bytes) osl_pktpush((osh), (skb), (bytes)) ++#define PKTPULL(osh, skb, bytes) osl_pktpull((osh), (skb), (bytes)) ++#define PKTTAG(skb) osl_pkttag((skb)) ++#define PKTTONATIVE(osh, pkt) osl_pkt_tonative((osh), (pkt)) ++#define PKTLINK(skb) osl_pktlink((skb)) ++#define PKTSETLINK(skb, x) osl_pktsetlink((skb), (x)) ++#define PKTPRIO(skb) osl_pktprio((skb)) ++#define PKTSETPRIO(skb, x) osl_pktsetprio((skb), (x)) ++#define PKTSHARED(skb) osl_pktshared((skb)) ++#define PKTSETPOOL(osh, skb, x, y) do {} while (0) ++#define PKTPOOL(osh, skb) FALSE ++ ++extern void *osl_pktget(osl_t *osh, uint len); ++extern void *osl_pktdup(osl_t *osh, void *skb); ++extern void *osl_pkt_frmnative(osl_t *osh, void *skb); ++extern void osl_pktfree(osl_t *osh, void *skb, bool send); ++extern uchar *osl_pktdata(osl_t *osh, void *skb); ++extern uint osl_pktlen(osl_t *osh, void *skb); ++extern uint osl_pktheadroom(osl_t *osh, void *skb); ++extern uint osl_pkttailroom(osl_t *osh, void *skb); ++extern void *osl_pktnext(osl_t *osh, void *skb); ++extern void osl_pktsetnext(void *skb, void *x); ++extern void osl_pktsetlen(osl_t *osh, void *skb, uint len); ++extern uchar *osl_pktpush(osl_t *osh, void *skb, int bytes); ++extern uchar *osl_pktpull(osl_t *osh, void *skb, int bytes); ++extern void *osl_pkttag(void *skb); ++extern void *osl_pktlink(void *skb); ++extern void osl_pktsetlink(void *skb, void *x); ++extern uint osl_pktprio(void *skb); ++extern void osl_pktsetprio(void *skb, uint x); ++extern struct sk_buff *osl_pkt_tonative(osl_t *osh, void *pkt); ++extern bool osl_pktshared(void *skb); ++ ++ ++#endif /* BINOSL */ ++ ++#define PKTALLOCED(osh) osl_pktalloced(osh) ++extern uint osl_pktalloced(osl_t *osh); ++ ++#define DMA_MAP(osh, va, size, direction, p, dmah) \ ++ osl_dma_map((osh), (va), (size), (direction), (p), (dmah)) ++ ++#else /* ! BCMDRIVER */ ++ ++ ++/* ASSERT */ ++ #define ASSERT(exp) do {} while (0) ++ ++/* MALLOC and MFREE */ ++#define MALLOC(o, l) malloc(l) ++#define MFREE(o, p, l) free(p) ++#include ++ ++/* str* and mem* functions */ ++#include ++ ++/* *printf functions */ ++#include ++ ++/* bcopy, bcmp, and bzero */ ++extern void bcopy(const void *src, void *dst, size_t len); ++extern int bcmp(const void *b1, const void *b2, size_t len); ++extern void bzero(void *b, size_t len); ++#endif /* ! BCMDRIVER */ ++ ++#endif /* _linux_osl_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/linuxver.h b/drivers/net/ethernet/broadcom/gmac/src/include/linuxver.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/linuxver.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/linuxver.h 2017-11-09 17:53:43.969290000 +0800 +@@ -0,0 +1,662 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Linux-specific abstractions to gain some independence from linux kernel versions. ++ * Pave over some 2.2 versus 2.4 versus 2.6 kernel differences. ++ * ++ * $Id: linuxver.h 312774 2012-02-03 22:20:14Z $ ++ */ ++ ++#ifndef _linuxver_h_ ++#define _linuxver_h_ ++ ++#include ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) ++#include ++#else ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) ++#include ++#else ++#include ++#endif ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) */ ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0)) ++/* __NO_VERSION__ must be defined for all linkables except one in 2.2 */ ++#ifdef __UNDEF_NO_VERSION__ ++#undef __NO_VERSION__ ++#else ++#define __NO_VERSION__ ++#endif ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0) */ ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) ++#define module_param(_name_, _type_, _perm_) MODULE_PARM(_name_, "i") ++#define module_param_string(_name_, _string_, _size_, _perm_) \ ++ MODULE_PARM(_string_, "c" __MODULE_STRING(_size_)) ++#endif ++ ++/* linux/malloc.h is deprecated, use linux/slab.h instead. */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 9)) ++#include ++#else ++#include ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) ++#include ++#else ++#include ++#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)) ++#undef IP_TOS ++#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)) */ ++#include ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 41)) ++#include ++#else ++#include ++#ifndef work_struct ++#define work_struct tq_struct ++#endif ++#ifndef INIT_WORK ++#define INIT_WORK(_work, _func, _data) INIT_TQUEUE((_work), (_func), (_data)) ++#endif ++#ifndef schedule_work ++#define schedule_work(_work) schedule_task((_work)) ++#endif ++#ifndef flush_scheduled_work ++#define flush_scheduled_work() flush_scheduled_tasks() ++#endif ++#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 41) */ ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) ++#define MY_INIT_WORK(_work, _func) INIT_WORK(_work, _func) ++#else ++#define MY_INIT_WORK(_work, _func) INIT_WORK(_work, _func, _work) ++typedef void (*work_func_t)(void *work); ++#endif /* >= 2.6.20 */ ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) ++/* Some distributions have their own 2.6.x compatibility layers */ ++#ifndef IRQ_NONE ++typedef void irqreturn_t; ++#define IRQ_NONE ++#define IRQ_HANDLED ++#define IRQ_RETVAL(x) ++#endif ++#else ++typedef irqreturn_t(*FN_ISR) (int irq, void *dev_id, struct pt_regs *ptregs); ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) */ ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) ++#define IRQF_SHARED SA_SHIRQ ++#endif /* < 2.6.18 */ ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 17) ++#ifdef CONFIG_NET_RADIO ++#define CONFIG_WIRELESS_EXT ++#endif ++#endif /* < 2.6.17 */ ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 67) ++#define MOD_INC_USE_COUNT ++#define MOD_DEC_USE_COUNT ++#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 67) */ ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) ++#include ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) ++#include ++#endif ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) ++#include ++#else ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14) ++#include ++#endif ++#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30) */ ++ ++#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE) ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27) ++#include ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27) */ ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) ++#include ++#include ++#endif ++#include ++#include ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 69)) ++/* In 2.5 (as of 2.5.69 at least) there is a cs_error exported which ++ * does this, but it's not in 2.4 so we do our own for now. ++ */ ++static inline void ++cs_error(client_handle_t handle, int func, int ret) ++{ ++ error_info_t err = { func, ret }; ++ CardServices(ReportError, handle, &err); ++} ++#endif ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 16)) ++ ++typedef struct pcmcia_device dev_link_t; ++ ++#endif ++ ++#endif /* CONFIG_PCMCIA */ ++ ++#ifndef __exit ++#define __exit ++#endif ++#ifndef __devexit ++#define __devexit ++#endif ++#ifndef __devinit ++#define __devinit __init ++#endif ++#ifndef __devinitdata ++#define __devinitdata ++#endif ++#ifndef __devexit_p ++#define __devexit_p(x) x ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)) ++ ++#define pci_get_drvdata(dev) (dev)->sysdata ++#define pci_set_drvdata(dev, value) (dev)->sysdata = (value) ++ ++/* ++ * New-style (2.4.x) PCI/hot-pluggable PCI/CardBus registration ++ */ ++ ++struct pci_device_id { ++ unsigned int vendor, device; /* Vendor and device ID or PCI_ANY_ID */ ++ unsigned int subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */ ++ unsigned int class, class_mask; /* (class,subclass,prog-if) triplet */ ++ unsigned long driver_data; /* Data private to the driver */ ++}; ++ ++struct pci_driver { ++ struct list_head node; ++ char *name; ++ const struct pci_device_id *id_table; /* NULL if wants all devices */ ++ int (*probe)(struct pci_dev *dev, ++ const struct pci_device_id *id); /* New device inserted */ ++ void (*remove)(struct pci_dev *dev); /* Device removed (NULL if not a hot-plug ++ * capable driver) ++ */ ++ void (*suspend)(struct pci_dev *dev); /* Device suspended */ ++ void (*resume)(struct pci_dev *dev); /* Device woken up */ ++}; ++ ++#define MODULE_DEVICE_TABLE(type, name) ++#define PCI_ANY_ID (~0) ++ ++/* compatpci.c */ ++#define pci_module_init pci_register_driver ++extern int pci_register_driver(struct pci_driver *drv); ++extern void pci_unregister_driver(struct pci_driver *drv); ++ ++#endif /* PCI registration */ ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)) ++#define pci_module_init pci_register_driver ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18)) ++#ifdef MODULE ++#define module_init(x) int init_module(void) { return x(); } ++#define module_exit(x) void cleanup_module(void) { x(); } ++#else ++#define module_init(x) __initcall(x); ++#define module_exit(x) __exitcall(x); ++#endif ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18) */ ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31) ++#define WL_USE_NETDEV_OPS ++#else ++#undef WL_USE_NETDEV_OPS ++#endif ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)) && defined(CONFIG_RFKILL) ++#define WL_CONFIG_RFKILL ++#else ++#undef WL_CONFIG_RFKILL ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 48)) ++#define list_for_each(pos, head) \ ++ for (pos = (head)->next; pos != (head); pos = pos->next) ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 13)) ++#define pci_resource_start(dev, bar) ((dev)->base_address[(bar)]) ++#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 44)) ++#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start) ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 23)) ++#define pci_enable_device(dev) do { } while (0) ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 14)) ++#define net_device device ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 42)) ++ ++/* ++ * DMA mapping ++ * ++ * See linux/Documentation/DMA-mapping.txt ++ */ ++ ++#ifndef PCI_DMA_TODEVICE ++#define PCI_DMA_TODEVICE 1 ++#define PCI_DMA_FROMDEVICE 2 ++#endif ++ ++typedef u32 dma_addr_t; ++ ++/* Pure 2^n version of get_order */ ++static inline int get_order(unsigned long size) ++{ ++ int order; ++ ++ size = (size-1) >> (PAGE_SHIFT-1); ++ order = -1; ++ do { ++ size >>= 1; ++ order++; ++ } while (size); ++ return order; ++} ++ ++static inline void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, ++ dma_addr_t *dma_handle) ++{ ++ void *ret; ++ int gfp = GFP_ATOMIC | GFP_DMA; ++ ++ ret = (void *)__get_free_pages(gfp, get_order(size)); ++ ++ if (ret != NULL) { ++ memset(ret, 0, size); ++ *dma_handle = virt_to_bus(ret); ++ } ++ return ret; ++} ++static inline void pci_free_consistent(struct pci_dev *hwdev, size_t size, ++ void *vaddr, dma_addr_t dma_handle) ++{ ++ free_pages((unsigned long)vaddr, get_order(size)); ++} ++#ifdef ILSIM ++extern uint pci_map_single(void *dev, void *va, uint size, int direction); ++extern void pci_unmap_single(void *dev, uint pa, uint size, int direction); ++#else ++#define pci_map_single(cookie, address, size, dir) virt_to_bus(address) ++#define pci_unmap_single(cookie, address, size, dir) ++#endif ++ ++#endif /* DMA mapping */ ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 43)) ++ ++#define dev_kfree_skb_any(a) dev_kfree_skb(a) ++#define netif_down(dev) do { (dev)->start = 0; } while (0) ++ ++/* pcmcia-cs provides its own netdevice compatibility layer */ ++#ifndef _COMPAT_NETDEVICE_H ++ ++/* ++ * SoftNet ++ * ++ * For pre-softnet kernels we need to tell the upper layer not to ++ * re-enter start_xmit() while we are in there. However softnet ++ * guarantees not to enter while we are in there so there is no need ++ * to do the netif_stop_queue() dance unless the transmit queue really ++ * gets stuck. This should also improve performance according to tests ++ * done by Aman Singla. ++ */ ++ ++#define dev_kfree_skb_irq(a) dev_kfree_skb(a) ++#define netif_wake_queue(dev) \ ++ do { clear_bit(0, &(dev)->tbusy); mark_bh(NET_BH); } while (0) ++#define netif_stop_queue(dev) set_bit(0, &(dev)->tbusy) ++ ++static inline void netif_start_queue(struct net_device *dev) ++{ ++ dev->tbusy = 0; ++ dev->interrupt = 0; ++ dev->start = 1; ++} ++ ++#define netif_queue_stopped(dev) (dev)->tbusy ++#define netif_running(dev) (dev)->start ++ ++#endif /* _COMPAT_NETDEVICE_H */ ++ ++#define netif_device_attach(dev) netif_start_queue(dev) ++#define netif_device_detach(dev) netif_stop_queue(dev) ++ ++/* 2.4.x renamed bottom halves to tasklets */ ++#define tasklet_struct tq_struct ++static inline void tasklet_schedule(struct tasklet_struct *tasklet) ++{ ++ queue_task(tasklet, &tq_immediate); ++ mark_bh(IMMEDIATE_BH); ++} ++ ++static inline void tasklet_init(struct tasklet_struct *tasklet, ++ void (*func)(unsigned long), ++ unsigned long data) ++{ ++ tasklet->next = NULL; ++ tasklet->sync = 0; ++ tasklet->routine = (void (*)(void *))func; ++ tasklet->data = (void *)data; ++} ++#define tasklet_kill(tasklet) { do {} while (0); } ++ ++/* 2.4.x introduced del_timer_sync() */ ++#define del_timer_sync(timer) del_timer(timer) ++ ++#else ++ ++#define netif_down(dev) ++ ++#endif /* SoftNet */ ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 3)) ++ ++/* ++ * Emit code to initialise a tq_struct's routine and data pointers ++ */ ++#define PREPARE_TQUEUE(_tq, _routine, _data) \ ++ do { \ ++ (_tq)->routine = _routine; \ ++ (_tq)->data = _data; \ ++ } while (0) ++ ++/* ++ * Emit code to initialise all of a tq_struct ++ */ ++#define INIT_TQUEUE(_tq, _routine, _data) \ ++ do { \ ++ INIT_LIST_HEAD(&(_tq)->list); \ ++ (_tq)->sync = 0; \ ++ PREPARE_TQUEUE((_tq), (_routine), (_data)); \ ++ } while (0) ++ ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 3) */ ++ ++/* Power management related macro & routines */ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 9) ++#define PCI_SAVE_STATE(a, b) pci_save_state(a) ++#define PCI_RESTORE_STATE(a, b) pci_restore_state(a) ++#else ++#define PCI_SAVE_STATE(a, b) pci_save_state(a, b) ++#define PCI_RESTORE_STATE(a, b) pci_restore_state(a, b) ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 6)) ++static inline int ++pci_save_state(struct pci_dev *dev, u32 *buffer) ++{ ++ int i; ++ if (buffer) { ++ for (i = 0; i < 16; i++) ++ pci_read_config_dword(dev, i * 4, &buffer[i]); ++ } ++ return 0; ++} ++ ++static inline int ++pci_restore_state(struct pci_dev *dev, u32 *buffer) ++{ ++ int i; ++ ++ if (buffer) { ++ for (i = 0; i < 16; i++) ++ pci_write_config_dword(dev, i * 4, buffer[i]); ++ } ++ /* ++ * otherwise, write the context information we know from bootup. ++ * This works around a problem where warm-booting from Windows ++ * combined with a D3(hot)->D0 transition causes PCI config ++ * header data to be forgotten. ++ */ ++ else { ++ for (i = 0; i < 6; i ++) ++ pci_write_config_dword(dev, ++ PCI_BASE_ADDRESS_0 + (i * 4), ++ pci_resource_start(dev, i)); ++ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); ++ } ++ return 0; ++} ++#endif /* PCI power management */ ++ ++/* Old cp0 access macros deprecated in 2.4.19 */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 19)) ++#define read_c0_count() read_32bit_cp0_register(CP0_COUNT) ++#endif ++ ++/* Module refcount handled internally in 2.6.x */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)) ++#ifndef SET_MODULE_OWNER ++#define SET_MODULE_OWNER(dev) do {} while (0) ++#define OLD_MOD_INC_USE_COUNT MOD_INC_USE_COUNT ++#define OLD_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT ++#else ++#define OLD_MOD_INC_USE_COUNT do {} while (0) ++#define OLD_MOD_DEC_USE_COUNT do {} while (0) ++#endif ++#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) */ ++#ifndef SET_MODULE_OWNER ++#define SET_MODULE_OWNER(dev) do {} while (0) ++#endif ++#ifndef MOD_INC_USE_COUNT ++#define MOD_INC_USE_COUNT do {} while (0) ++#endif ++#ifndef MOD_DEC_USE_COUNT ++#define MOD_DEC_USE_COUNT do {} while (0) ++#endif ++#define OLD_MOD_INC_USE_COUNT MOD_INC_USE_COUNT ++#define OLD_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) */ ++ ++#ifndef SET_NETDEV_DEV ++#define SET_NETDEV_DEV(net, pdev) do {} while (0) ++#endif ++ ++#ifndef HAVE_FREE_NETDEV ++#define free_netdev(dev) kfree(dev) ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) ++/* struct packet_type redefined in 2.6.x */ ++#define af_packet_priv data ++#endif ++ ++/* suspend args */ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) ++#define DRV_SUSPEND_STATE_TYPE pm_message_t ++#else ++#define DRV_SUSPEND_STATE_TYPE uint32 ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) ++#define CHECKSUM_HW CHECKSUM_PARTIAL ++#endif ++ ++typedef struct { ++ void *parent; /* some external entity that the thread supposed to work for */ ++ struct task_struct *p_task; ++ long thr_pid; ++ int prio; /* priority */ ++ struct semaphore sema; ++ int terminated; ++ struct completion completed; ++} tsk_ctl_t; ++ ++ ++/* requires tsk_ctl_t tsk argument, the caller's priv data is passed in owner ptr */ ++/* note this macro assumes there may be only one context waiting on thread's completion */ ++#ifdef DHD_DEBUG ++#define DBG_THR(x) printk x ++#else ++#define DBG_THR(x) ++#endif ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) ++#define SMP_RD_BARRIER_DEPENDS(x) smp_read_barrier_depends(x) ++#else ++#define SMP_RD_BARRIER_DEPENDS(x) smp_rmb(x) ++#endif ++ ++ ++#define PROC_START(thread_func, owner, tsk_ctl, flags) \ ++{ \ ++ sema_init(&((tsk_ctl)->sema), 0); \ ++ init_completion(&((tsk_ctl)->completed)); \ ++ (tsk_ctl)->parent = owner; \ ++ (tsk_ctl)->terminated = FALSE; \ ++ (tsk_ctl)->thr_pid = kernel_thread(thread_func, tsk_ctl, flags); \ ++ if ((tsk_ctl)->thr_pid > 0) \ ++ wait_for_completion(&((tsk_ctl)->completed)); \ ++ DBG_THR(("%s thr:%lx started\n", __FUNCTION__, (tsk_ctl)->thr_pid)); \ ++} ++ ++#define PROC_STOP(tsk_ctl) \ ++{ \ ++ (tsk_ctl)->terminated = TRUE; \ ++ smp_wmb(); \ ++ up(&((tsk_ctl)->sema)); \ ++ wait_for_completion(&((tsk_ctl)->completed)); \ ++ DBG_THR(("%s thr:%lx terminated OK\n", __FUNCTION__, (tsk_ctl)->thr_pid)); \ ++ (tsk_ctl)->thr_pid = -1; \ ++} ++ ++/* ----------------------- */ ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)) ++#define KILL_PROC(nr, sig) \ ++{ \ ++struct task_struct *tsk; \ ++struct pid *pid; \ ++pid = find_get_pid((pid_t)nr); \ ++tsk = pid_task(pid, PIDTYPE_PID); \ ++if (tsk) send_sig(sig, tsk, 1); \ ++} ++#else ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && (LINUX_VERSION_CODE <= \ ++ KERNEL_VERSION(2, 6, 30)) ++#define KILL_PROC(pid, sig) \ ++{ \ ++ struct task_struct *tsk; \ ++ tsk = find_task_by_vpid(pid); \ ++ if (tsk) send_sig(sig, tsk, 1); \ ++} ++#else ++#define KILL_PROC(pid, sig) \ ++{ \ ++ kill_proc(pid, sig, 1); \ ++} ++#endif ++#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31) */ ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) ++#include ++#include ++#else ++#include ++ ++#define __wait_event_interruptible_timeout(wq, condition, ret) \ ++do { \ ++ wait_queue_t __wait; \ ++ init_waitqueue_entry(&__wait, current); \ ++ \ ++ add_wait_queue(&wq, &__wait); \ ++ for (;;) { \ ++ set_current_state(TASK_INTERRUPTIBLE); \ ++ if (condition) \ ++ break; \ ++ if (!signal_pending(current)) { \ ++ ret = schedule_timeout(ret); \ ++ if (!ret) \ ++ break; \ ++ continue; \ ++ } \ ++ ret = -ERESTARTSYS; \ ++ break; \ ++ } \ ++ current->state = TASK_RUNNING; \ ++ remove_wait_queue(&wq, &__wait); \ ++} while (0) ++ ++#define wait_event_interruptible_timeout(wq, condition, timeout) \ ++({ \ ++ long __ret = timeout; \ ++ if (!(condition)) \ ++ __wait_event_interruptible_timeout(wq, condition, __ret); \ ++ __ret; \ ++}) ++ ++#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) */ ++ ++/* ++For < 2.6.24, wl creates its own netdev but doesn't ++align the priv area like the genuine alloc_netdev(). ++Since netdev_priv() always gives us the aligned address, it will ++not match our unaligned address for < 2.6.24 ++*/ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)) ++#define DEV_PRIV(dev) (dev->priv) ++#else ++#define DEV_PRIV(dev) netdev_priv(dev) ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) ++#define WL_ISR(i, d, p) wl_isr((i), (d)) ++#else ++#define WL_ISR(i, d, p) wl_isr((i), (d), (p)) ++#endif /* < 2.6.20 */ ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) ++#define netdev_priv(dev) dev->priv ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) */ ++ ++#endif /* _linuxver_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/osl.h b/drivers/net/ethernet/broadcom/gmac/src/include/osl.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/osl.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/osl.h 2017-11-09 17:53:43.969308000 +0800 +@@ -0,0 +1,143 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * OS Abstraction Layer ++ * ++ * $Id: osl.h 321101 2012-03-14 02:53:01Z $ ++ */ ++ ++#ifndef _osl_h_ ++#define _osl_h_ ++ ++/* osl handle type forward declaration */ ++typedef struct osl_info osl_t; ++typedef struct osl_dmainfo osldma_t; ++ ++#define OSL_PKTTAG_SZ 32 /* Size of PktTag */ ++ ++/* Drivers use PKTFREESETCB to register a callback function when a packet is freed by OSL */ ++typedef void (*pktfree_cb_fn_t)(void *ctx, void *pkt, unsigned int status); ++ ++/* Drivers use REGOPSSET() to register register read/write funcitons */ ++typedef unsigned int (*osl_rreg_fn_t)(void *ctx, volatile void *reg, unsigned int size); ++typedef void (*osl_wreg_fn_t)(void *ctx, volatile void *reg, unsigned int val, unsigned int size); ++ ++#ifdef __mips__ ++#define PREF_LOAD 0 ++#define PREF_STORE 1 ++#define PREF_LOAD_STREAMED 4 ++#define PREF_STORE_STREAMED 5 ++#define PREF_LOAD_RETAINED 6 ++#define PREF_STORE_RETAINED 7 ++#define PREF_WBACK_INV 25 ++#define PREF_PREPARE4STORE 30 ++ ++ ++#define MAKE_PREFETCH_FN(hint) \ ++static inline void prefetch_##hint(const void *addr) \ ++{ \ ++ __asm__ __volatile__(\ ++ " .set mips4 \n" \ ++ " pref %0, (%1) \n" \ ++ " .set mips0 \n" \ ++ : \ ++ : "i" (hint), "r" (addr)); \ ++} ++ ++#define MAKE_PREFETCH_RANGE_FN(hint) \ ++static inline void prefetch_range_##hint(const void *addr, int len) \ ++{ \ ++ int size = len; \ ++ while (size > 0) { \ ++ prefetch_##hint(addr); \ ++ size -= 32; \ ++ } \ ++} ++ ++MAKE_PREFETCH_FN(PREF_LOAD) ++MAKE_PREFETCH_RANGE_FN(PREF_LOAD) ++MAKE_PREFETCH_FN(PREF_STORE) ++MAKE_PREFETCH_RANGE_FN(PREF_STORE) ++MAKE_PREFETCH_FN(PREF_LOAD_STREAMED) ++MAKE_PREFETCH_RANGE_FN(PREF_LOAD_STREAMED) ++MAKE_PREFETCH_FN(PREF_STORE_STREAMED) ++MAKE_PREFETCH_RANGE_FN(PREF_STORE_STREAMED) ++MAKE_PREFETCH_FN(PREF_LOAD_RETAINED) ++MAKE_PREFETCH_RANGE_FN(PREF_LOAD_RETAINED) ++MAKE_PREFETCH_FN(PREF_STORE_RETAINED) ++MAKE_PREFETCH_RANGE_FN(PREF_STORE_RETAINED) ++#endif /* __mips__ */ ++ ++#if defined(linux) ++#include ++#else ++#error "Unsupported OSL requested" ++#endif ++ ++#ifndef PKTDBG_TRACE ++#define PKTDBG_TRACE(osh, pkt, bit) ++#endif ++ ++#ifndef PKTCTFMAP ++#define PKTCTFMAP(osh, p) ++#endif /* PKTCTFMAP */ ++ ++/* -------------------------------------------------------------------------- ++** Register manipulation macros. ++*/ ++ ++#define SET_REG(osh, r, mask, val) W_REG((osh), (r), ((R_REG((osh), r) & ~(mask)) | (val))) ++ ++#ifndef AND_REG ++#define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v)) ++#endif /* !AND_REG */ ++ ++#ifndef OR_REG ++#define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v)) ++#endif /* !OR_REG */ ++ ++#if !defined(OSL_SYSUPTIME) ++#define OSL_SYSUPTIME() (0) ++#define OSL_SYSUPTIME_SUPPORT FALSE ++#else ++#define OSL_SYSUPTIME_SUPPORT TRUE ++#endif /* OSL_SYSUPTIME */ ++ ++#define PKTCGETATTR(s) (0) ++#define PKTCSETATTR(skb, f, p, b) ++#define PKTCCLRATTR(skb) ++#define PKTCCNT(skb) (1) ++#define PKTCLEN(skb) PKTLEN(NULL, skb) ++#define PKTCGETFLAGS(skb) (0) ++#define PKTCSETFLAGS(skb, f) ++#define PKTCCLRFLAGS(skb) ++#define PKTCFLAGS(skb) (0) ++#define PKTCSETCNT(skb, c) ++#define PKTCINCRCNT(skb) ++#define PKTCADDCNT(skb, c) ++#define PKTCSETLEN(skb, l) ++#define PKTCADDLEN(skb, l) ++#define PKTCSETFLAG(skb, fb) ++#define PKTCCLRFLAG(skb, fb) ++#define PKTCLINK(skb) NULL ++#define PKTSETCLINK(skb, x) ++#undef PKTISCHAINED ++#define PKTISCHAINED(skb) FALSE ++#define FOREACH_CHAINED_PKT(skb, nskb) \ ++ for ((nskb) = NULL; (skb) != NULL; (skb) = (nskb)) ++#define PKTCFREE PKTFREE ++ ++ ++#endif /* _osl_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/packed_section_end.h b/drivers/net/ethernet/broadcom/gmac/src/include/packed_section_end.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/packed_section_end.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/packed_section_end.h 2017-11-09 17:53:43.970305000 +0800 +@@ -0,0 +1,71 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Declare directives for structure packing. No padding will be provided ++ * between the members of packed structures, and therefore, there is no ++ * guarantee that structure members will be aligned. ++ * ++ * Declaring packed structures is compiler specific. In order to handle all ++ * cases, packed structures should be delared as: ++ * ++ * #include ++ * ++ * typedef BWL_PRE_PACKED_STRUCT struct foobar_t { ++ * some_struct_members; ++ * } BWL_POST_PACKED_STRUCT foobar_t; ++ * ++ * #include ++ * ++ * ++ * $Id: packed_section_end.h 241182 2011-02-17 21:50:03Z $ ++ */ ++ ++ ++/* Error check - BWL_PACKED_SECTION is defined in packed_section_start.h ++ * and undefined in packed_section_end.h. If it is NOT defined at this ++ * point, then there is a missing include of packed_section_start.h. ++ */ ++#ifdef BWL_PACKED_SECTION ++ #undef BWL_PACKED_SECTION ++#else ++ #error "BWL_PACKED_SECTION is NOT defined!" ++#endif ++ ++ ++#if defined(_MSC_VER) ++ /* Disable compiler warning about pragma pack changing alignment. */ ++ #pragma warning(disable:4103) ++ ++ /* The Microsoft compiler uses pragmas for structure packing. Other ++ * compilers use structure attribute modifiers. Refer to ++ * BWL_PRE_PACKED_STRUCT and BWL_POST_PACKED_STRUCT defined in ++ * typedefs.h ++ */ ++ #if defined(BWL_DEFAULT_PACKING) ++ /* require default structure packing */ ++ #pragma pack(pop) ++ #undef BWL_DEFAULT_PACKING ++ #else /* BWL_PACKED_SECTION */ ++ #pragma pack() ++ #endif /* BWL_PACKED_SECTION */ ++#endif /* _MSC_VER */ ++ ++ ++/* Compiler-specific directives for structure packing are declared in ++ * packed_section_start.h. This marks the end of the structure packing section, ++ * so, undef them here. ++ */ ++#undef BWL_PRE_PACKED_STRUCT ++#undef BWL_POST_PACKED_STRUCT +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/packed_section_start.h b/drivers/net/ethernet/broadcom/gmac/src/include/packed_section_start.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/packed_section_start.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/packed_section_start.h 2017-11-09 17:53:43.971302000 +0800 +@@ -0,0 +1,76 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Declare directives for structure packing. No padding will be provided ++ * between the members of packed structures, and therefore, there is no ++ * guarantee that structure members will be aligned. ++ * ++ * Declaring packed structures is compiler specific. In order to handle all ++ * cases, packed structures should be delared as: ++ * ++ * #include ++ * ++ * typedef BWL_PRE_PACKED_STRUCT struct foobar_t { ++ * some_struct_members; ++ * } BWL_POST_PACKED_STRUCT foobar_t; ++ * ++ * #include ++ * ++ * ++ * $Id: packed_section_start.h 286783 2011-09-29 06:18:57Z $ ++ */ ++ ++ ++/* Error check - BWL_PACKED_SECTION is defined in packed_section_start.h ++ * and undefined in packed_section_end.h. If it is already defined at this ++ * point, then there is a missing include of packed_section_end.h. ++ */ ++#ifdef BWL_PACKED_SECTION ++ #error "BWL_PACKED_SECTION is already defined!" ++#else ++ #define BWL_PACKED_SECTION ++#endif ++ ++ ++#if defined(_MSC_VER) ++ /* Disable compiler warning about pragma pack changing alignment. */ ++ #pragma warning(disable:4103) ++ ++ /* The Microsoft compiler uses pragmas for structure packing. Other ++ * compilers use structure attribute modifiers. Refer to ++ * BWL_PRE_PACKED_STRUCT and BWL_POST_PACKED_STRUCT defined below. ++ */ ++ #if defined(BWL_DEFAULT_PACKING) ++ /* Default structure packing */ ++ #pragma pack(push, 8) ++ #else /* BWL_PACKED_SECTION */ ++ #pragma pack(1) ++ #endif /* BWL_PACKED_SECTION */ ++#endif /* _MSC_VER */ ++ ++ ++/* Declare compiler-specific directives for structure packing. */ ++#if defined(_MSC_VER) ++ #define BWL_PRE_PACKED_STRUCT ++ #define BWL_POST_PACKED_STRUCT ++#elif defined(__GNUC__) || defined(__lint) ++ #define BWL_PRE_PACKED_STRUCT ++ #define BWL_POST_PACKED_STRUCT __attribute__ ((packed)) ++#elif defined(__CC_ARM) ++ #define BWL_PRE_PACKED_STRUCT __packed ++ #define BWL_POST_PACKED_STRUCT ++#else ++ #error "Unknown compiler!" ++#endif +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/pcicfg.h b/drivers/net/ethernet/broadcom/gmac/src/include/pcicfg.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/pcicfg.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/pcicfg.h 2017-11-09 17:53:43.972306000 +0800 +@@ -0,0 +1,569 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * pcicfg.h: PCI configuration constants and structures. ++ * ++ * $Id: pcicfg.h 316716 2012-02-23 04:39:13Z $ ++ */ ++ ++#ifndef _h_pcicfg_ ++#define _h_pcicfg_ ++ ++#ifndef LINUX_POSTMOGRIFY_REMOVAL ++/* The following inside ifndef's so we don't collide with NTDDK.H */ ++#ifndef PCI_MAX_BUS ++#define PCI_MAX_BUS 0x100 ++#endif ++#ifndef PCI_MAX_DEVICES ++#define PCI_MAX_DEVICES 0x20 ++#endif ++#ifndef PCI_MAX_FUNCTION ++#define PCI_MAX_FUNCTION 0x8 ++#endif ++ ++#ifndef PCI_INVALID_VENDORID ++#define PCI_INVALID_VENDORID 0xffff ++#endif ++#ifndef PCI_INVALID_DEVICEID ++#define PCI_INVALID_DEVICEID 0xffff ++#endif ++ ++ ++/* Convert between bus-slot-function-register and config addresses */ ++ ++#define PCICFG_BUS_SHIFT 16 /* Bus shift */ ++#define PCICFG_SLOT_SHIFT 11 /* Slot shift */ ++#define PCICFG_FUN_SHIFT 8 /* Function shift */ ++#define PCICFG_OFF_SHIFT 0 /* Register shift */ ++ ++#define PCICFG_BUS_MASK 0xff /* Bus mask */ ++#define PCICFG_SLOT_MASK 0x1f /* Slot mask */ ++#define PCICFG_FUN_MASK 7 /* Function mask */ ++#define PCICFG_OFF_MASK 0xff /* Bus mask */ ++ ++#define PCI_CONFIG_ADDR(b, s, f, o) \ ++ ((((b) & PCICFG_BUS_MASK) << PCICFG_BUS_SHIFT) \ ++ | (((s) & PCICFG_SLOT_MASK) << PCICFG_SLOT_SHIFT) \ ++ | (((f) & PCICFG_FUN_MASK) << PCICFG_FUN_SHIFT) \ ++ | (((o) & PCICFG_OFF_MASK) << PCICFG_OFF_SHIFT)) ++ ++#define PCI_CONFIG_BUS(a) (((a) >> PCICFG_BUS_SHIFT) & PCICFG_BUS_MASK) ++#define PCI_CONFIG_SLOT(a) (((a) >> PCICFG_SLOT_SHIFT) & PCICFG_SLOT_MASK) ++#define PCI_CONFIG_FUN(a) (((a) >> PCICFG_FUN_SHIFT) & PCICFG_FUN_MASK) ++#define PCI_CONFIG_OFF(a) (((a) >> PCICFG_OFF_SHIFT) & PCICFG_OFF_MASK) ++ ++/* PCIE Config space accessing MACROS */ ++ ++#define PCIECFG_BUS_SHIFT 24 /* Bus shift */ ++#define PCIECFG_SLOT_SHIFT 19 /* Slot/Device shift */ ++#define PCIECFG_FUN_SHIFT 16 /* Function shift */ ++#define PCIECFG_OFF_SHIFT 0 /* Register shift */ ++ ++#define PCIECFG_BUS_MASK 0xff /* Bus mask */ ++#define PCIECFG_SLOT_MASK 0x1f /* Slot/Device mask */ ++#define PCIECFG_FUN_MASK 7 /* Function mask */ ++#define PCIECFG_OFF_MASK 0xfff /* Register mask */ ++ ++#define PCIE_CONFIG_ADDR(b, s, f, o) \ ++ ((((b) & PCIECFG_BUS_MASK) << PCIECFG_BUS_SHIFT) \ ++ | (((s) & PCIECFG_SLOT_MASK) << PCIECFG_SLOT_SHIFT) \ ++ | (((f) & PCIECFG_FUN_MASK) << PCIECFG_FUN_SHIFT) \ ++ | (((o) & PCIECFG_OFF_MASK) << PCIECFG_OFF_SHIFT)) ++ ++#define PCIE_CONFIG_BUS(a) (((a) >> PCIECFG_BUS_SHIFT) & PCIECFG_BUS_MASK) ++#define PCIE_CONFIG_SLOT(a) (((a) >> PCIECFG_SLOT_SHIFT) & PCIECFG_SLOT_MASK) ++#define PCIE_CONFIG_FUN(a) (((a) >> PCIECFG_FUN_SHIFT) & PCIECFG_FUN_MASK) ++#define PCIE_CONFIG_OFF(a) (((a) >> PCIECFG_OFF_SHIFT) & PCIECFG_OFF_MASK) ++ ++/* The actual config space */ ++ ++#define PCI_BAR_MAX 6 ++ ++#define PCI_ROM_BAR 8 ++ ++#define PCR_RSVDA_MAX 2 ++ ++/* Bits in PCI bars' flags */ ++ ++#define PCIBAR_FLAGS 0xf ++#define PCIBAR_IO 0x1 ++#define PCIBAR_MEM1M 0x2 ++#define PCIBAR_MEM64 0x4 ++#define PCIBAR_PREFETCH 0x8 ++#define PCIBAR_MEM32_MASK 0xFFFFFF80 ++ ++/* pci config status reg has a bit to indicate that capability ptr is present */ ++ ++#define PCI_CAPPTR_PRESENT 0x0010 ++ ++typedef struct _pci_config_regs { ++ uint16 vendor; ++ uint16 device; ++ uint16 command; ++ uint16 status; ++ uint8 rev_id; ++ uint8 prog_if; ++ uint8 sub_class; ++ uint8 base_class; ++ uint8 cache_line_size; ++ uint8 latency_timer; ++ uint8 header_type; ++ uint8 bist; ++ uint32 base[PCI_BAR_MAX]; ++ uint32 cardbus_cis; ++ uint16 subsys_vendor; ++ uint16 subsys_id; ++ uint32 baserom; ++ uint32 rsvd_a[PCR_RSVDA_MAX]; ++ uint8 int_line; ++ uint8 int_pin; ++ uint8 min_gnt; ++ uint8 max_lat; ++ uint8 dev_dep[192]; ++} pci_config_regs; ++ ++#define SZPCR (sizeof (pci_config_regs)) ++#define MINSZPCR 64 /* offsetof (dev_dep[0] */ ++ ++#endif /* !LINUX_POSTMOGRIFY_REMOVAL */ ++/* A structure for the config registers is nice, but in most ++ * systems the config space is not memory mapped, so we need ++ * field offsetts. :-( ++ */ ++#define PCI_CFG_VID 0 ++#define PCI_CFG_DID 2 ++#define PCI_CFG_CMD 4 ++#define PCI_CFG_STAT 6 ++#define PCI_CFG_REV 8 ++#define PCI_CFG_PROGIF 9 ++#define PCI_CFG_SUBCL 0xa ++#define PCI_CFG_BASECL 0xb ++#define PCI_CFG_CLSZ 0xc ++#define PCI_CFG_LATTIM 0xd ++#define PCI_CFG_HDR 0xe ++#define PCI_CFG_BIST 0xf ++#define PCI_CFG_BAR0 0x10 ++#define PCI_CFG_BAR1 0x14 ++#define PCI_CFG_BAR2 0x18 ++#define PCI_CFG_BAR3 0x1c ++#define PCI_CFG_BAR4 0x20 ++#define PCI_CFG_BAR5 0x24 ++#define PCI_CFG_CIS 0x28 ++#define PCI_CFG_SVID 0x2c ++#define PCI_CFG_SSID 0x2e ++#define PCI_CFG_ROMBAR 0x30 ++#define PCI_CFG_CAPPTR 0x34 ++#define PCI_CFG_INT 0x3c ++#define PCI_CFG_PIN 0x3d ++#define PCI_CFG_MINGNT 0x3e ++#define PCI_CFG_MAXLAT 0x3f ++#define PCI_CFG_DEVCTRL 0xd8 ++#ifndef LINUX_POSTMOGRIFY_REMOVAL ++ ++#ifdef __NetBSD__ ++#undef PCI_CLASS_DISPLAY ++#undef PCI_CLASS_MEMORY ++#undef PCI_CLASS_BRIDGE ++#undef PCI_CLASS_INPUT ++#undef PCI_CLASS_DOCK ++#endif /* __NetBSD__ */ ++ ++#ifdef EFI ++#undef PCI_CLASS_BRIDGE ++#undef PCI_CLASS_OLD ++#undef PCI_CLASS_DISPLAY ++#undef PCI_CLASS_SERIAL ++#undef PCI_CLASS_SATELLITE ++#endif /* EFI */ ++ ++/* Classes and subclasses */ ++ ++typedef enum { ++ PCI_CLASS_OLD = 0, ++ PCI_CLASS_DASDI, ++ PCI_CLASS_NET, ++ PCI_CLASS_DISPLAY, ++ PCI_CLASS_MMEDIA, ++ PCI_CLASS_MEMORY, ++ PCI_CLASS_BRIDGE, ++ PCI_CLASS_COMM, ++ PCI_CLASS_BASE, ++ PCI_CLASS_INPUT, ++ PCI_CLASS_DOCK, ++ PCI_CLASS_CPU, ++ PCI_CLASS_SERIAL, ++ PCI_CLASS_INTELLIGENT = 0xe, ++ PCI_CLASS_SATELLITE, ++ PCI_CLASS_CRYPT, ++ PCI_CLASS_DSP, ++ PCI_CLASS_XOR = 0xfe ++} pci_classes; ++ ++typedef enum { ++ PCI_DASDI_SCSI, ++ PCI_DASDI_IDE, ++ PCI_DASDI_FLOPPY, ++ PCI_DASDI_IPI, ++ PCI_DASDI_RAID, ++ PCI_DASDI_OTHER = 0x80 ++} pci_dasdi_subclasses; ++ ++typedef enum { ++ PCI_NET_ETHER, ++ PCI_NET_TOKEN, ++ PCI_NET_FDDI, ++ PCI_NET_ATM, ++ PCI_NET_OTHER = 0x80 ++} pci_net_subclasses; ++ ++typedef enum { ++ PCI_DISPLAY_VGA, ++ PCI_DISPLAY_XGA, ++ PCI_DISPLAY_3D, ++ PCI_DISPLAY_OTHER = 0x80 ++} pci_display_subclasses; ++ ++typedef enum { ++ PCI_MMEDIA_VIDEO, ++ PCI_MMEDIA_AUDIO, ++ PCI_MMEDIA_PHONE, ++ PCI_MEDIA_OTHER = 0x80 ++} pci_mmedia_subclasses; ++ ++typedef enum { ++ PCI_MEMORY_RAM, ++ PCI_MEMORY_FLASH, ++ PCI_MEMORY_OTHER = 0x80 ++} pci_memory_subclasses; ++ ++typedef enum { ++ PCI_BRIDGE_HOST, ++ PCI_BRIDGE_ISA, ++ PCI_BRIDGE_EISA, ++ PCI_BRIDGE_MC, ++ PCI_BRIDGE_PCI, ++ PCI_BRIDGE_PCMCIA, ++ PCI_BRIDGE_NUBUS, ++ PCI_BRIDGE_CARDBUS, ++ PCI_BRIDGE_RACEWAY, ++ PCI_BRIDGE_OTHER = 0x80 ++} pci_bridge_subclasses; ++ ++typedef enum { ++ PCI_COMM_UART, ++ PCI_COMM_PARALLEL, ++ PCI_COMM_MULTIUART, ++ PCI_COMM_MODEM, ++ PCI_COMM_OTHER = 0x80 ++} pci_comm_subclasses; ++ ++typedef enum { ++ PCI_BASE_PIC, ++ PCI_BASE_DMA, ++ PCI_BASE_TIMER, ++ PCI_BASE_RTC, ++ PCI_BASE_PCI_HOTPLUG, ++ PCI_BASE_OTHER = 0x80 ++} pci_base_subclasses; ++ ++typedef enum { ++ PCI_INPUT_KBD, ++ PCI_INPUT_PEN, ++ PCI_INPUT_MOUSE, ++ PCI_INPUT_SCANNER, ++ PCI_INPUT_GAMEPORT, ++ PCI_INPUT_OTHER = 0x80 ++} pci_input_subclasses; ++ ++typedef enum { ++ PCI_DOCK_GENERIC, ++ PCI_DOCK_OTHER = 0x80 ++} pci_dock_subclasses; ++ ++typedef enum { ++ PCI_CPU_386, ++ PCI_CPU_486, ++ PCI_CPU_PENTIUM, ++ PCI_CPU_ALPHA = 0x10, ++ PCI_CPU_POWERPC = 0x20, ++ PCI_CPU_MIPS = 0x30, ++ PCI_CPU_COPROC = 0x40, ++ PCI_CPU_OTHER = 0x80 ++} pci_cpu_subclasses; ++ ++typedef enum { ++ PCI_SERIAL_IEEE1394, ++ PCI_SERIAL_ACCESS, ++ PCI_SERIAL_SSA, ++ PCI_SERIAL_USB, ++ PCI_SERIAL_FIBER, ++ PCI_SERIAL_SMBUS, ++ PCI_SERIAL_OTHER = 0x80 ++} pci_serial_subclasses; ++ ++typedef enum { ++ PCI_INTELLIGENT_I2O ++} pci_intelligent_subclasses; ++ ++typedef enum { ++ PCI_SATELLITE_TV, ++ PCI_SATELLITE_AUDIO, ++ PCI_SATELLITE_VOICE, ++ PCI_SATELLITE_DATA, ++ PCI_SATELLITE_OTHER = 0x80 ++} pci_satellite_subclasses; ++ ++typedef enum { ++ PCI_CRYPT_NETWORK, ++ PCI_CRYPT_ENTERTAINMENT, ++ PCI_CRYPT_OTHER = 0x80 ++} pci_crypt_subclasses; ++ ++typedef enum { ++ PCI_DSP_DPIO, ++ PCI_DSP_OTHER = 0x80 ++} pci_dsp_subclasses; ++ ++typedef enum { ++ PCI_XOR_QDMA, ++ PCI_XOR_OTHER = 0x80 ++} pci_xor_subclasses; ++ ++/* Header types */ ++#define PCI_HEADER_MULTI 0x80 ++#define PCI_HEADER_MASK 0x7f ++typedef enum { ++ PCI_HEADER_NORMAL, ++ PCI_HEADER_BRIDGE, ++ PCI_HEADER_CARDBUS ++} pci_header_types; ++ ++ ++/* Overlay for a PCI-to-PCI bridge */ ++ ++#define PPB_RSVDA_MAX 2 ++#define PPB_RSVDD_MAX 8 ++ ++typedef struct _ppb_config_regs { ++ uint16 vendor; ++ uint16 device; ++ uint16 command; ++ uint16 status; ++ uint8 rev_id; ++ uint8 prog_if; ++ uint8 sub_class; ++ uint8 base_class; ++ uint8 cache_line_size; ++ uint8 latency_timer; ++ uint8 header_type; ++ uint8 bist; ++ uint32 rsvd_a[PPB_RSVDA_MAX]; ++ uint8 prim_bus; ++ uint8 sec_bus; ++ uint8 sub_bus; ++ uint8 sec_lat; ++ uint8 io_base; ++ uint8 io_lim; ++ uint16 sec_status; ++ uint16 mem_base; ++ uint16 mem_lim; ++ uint16 pf_mem_base; ++ uint16 pf_mem_lim; ++ uint32 pf_mem_base_hi; ++ uint32 pf_mem_lim_hi; ++ uint16 io_base_hi; ++ uint16 io_lim_hi; ++ uint16 subsys_vendor; ++ uint16 subsys_id; ++ uint32 rsvd_b; ++ uint8 rsvd_c; ++ uint8 int_pin; ++ uint16 bridge_ctrl; ++ uint8 chip_ctrl; ++ uint8 diag_ctrl; ++ uint16 arb_ctrl; ++ uint32 rsvd_d[PPB_RSVDD_MAX]; ++ uint8 dev_dep[192]; ++} ppb_config_regs; ++ ++ ++/* PCI CAPABILITY DEFINES */ ++#define PCI_CAP_POWERMGMTCAP_ID 0x01 ++#define PCI_CAP_MSICAP_ID 0x05 ++#define PCI_CAP_VENDSPEC_ID 0x09 ++#define PCI_CAP_PCIECAP_ID 0x10 ++ ++/* Data structure to define the Message Signalled Interrupt facility ++ * Valid for PCI and PCIE configurations ++ */ ++typedef struct _pciconfig_cap_msi { ++ uint8 capID; ++ uint8 nextptr; ++ uint16 msgctrl; ++ uint32 msgaddr; ++} pciconfig_cap_msi; ++ ++/* Data structure to define the Power managment facility ++ * Valid for PCI and PCIE configurations ++ */ ++typedef struct _pciconfig_cap_pwrmgmt { ++ uint8 capID; ++ uint8 nextptr; ++ uint16 pme_cap; ++ uint16 pme_sts_ctrl; ++ uint8 pme_bridge_ext; ++ uint8 data; ++} pciconfig_cap_pwrmgmt; ++ ++#define PME_CAP_PM_STATES (0x1f << 27) /* Bits 31:27 states that can generate PME */ ++#define PME_CSR_OFFSET 0x4 /* 4-bytes offset */ ++#define PME_CSR_PME_EN (1 << 8) /* Bit 8 Enable generating of PME */ ++#define PME_CSR_PME_STAT (1 << 15) /* Bit 15 PME got asserted */ ++ ++/* Data structure to define the PCIE capability */ ++typedef struct _pciconfig_cap_pcie { ++ uint8 capID; ++ uint8 nextptr; ++ uint16 pcie_cap; ++ uint32 dev_cap; ++ uint16 dev_ctrl; ++ uint16 dev_status; ++ uint32 link_cap; ++ uint16 link_ctrl; ++ uint16 link_status; ++ uint32 slot_cap; ++ uint16 slot_ctrl; ++ uint16 slot_status; ++ uint16 root_ctrl; ++ uint16 root_cap; ++ uint32 root_status; ++} pciconfig_cap_pcie; ++ ++/* PCIE Enhanced CAPABILITY DEFINES */ ++#define PCIE_EXTCFG_OFFSET 0x100 ++#define PCIE_ADVERRREP_CAPID 0x0001 ++#define PCIE_VC_CAPID 0x0002 ++#define PCIE_DEVSNUM_CAPID 0x0003 ++#define PCIE_PWRBUDGET_CAPID 0x0004 ++ ++/* PCIE Extended configuration */ ++#define PCIE_ADV_CORR_ERR_MASK 0x114 ++#define CORR_ERR_RE (1 << 0) /* Receiver */ ++#define CORR_ERR_BT (1 << 6) /* Bad TLP */ ++#define CORR_ERR_BD (1 << 7) /* Bad DLLP */ ++#define CORR_ERR_RR (1 << 8) /* REPLAY_NUM rollover */ ++#define CORR_ERR_RT (1 << 12) /* Reply timer timeout */ ++#define ALL_CORR_ERRORS (CORR_ERR_RE | CORR_ERR_BT | CORR_ERR_BD | \ ++ CORR_ERR_RR | CORR_ERR_RT) ++ ++/* PCIE Root Control Register bits (Host mode only) */ ++#define PCIE_RC_CORR_SERR_EN 0x0001 ++#define PCIE_RC_NONFATAL_SERR_EN 0x0002 ++#define PCIE_RC_FATAL_SERR_EN 0x0004 ++#define PCIE_RC_PME_INT_EN 0x0008 ++#define PCIE_RC_CRS_EN 0x0010 ++ ++/* PCIE Root Capability Register bits (Host mode only) */ ++#define PCIE_RC_CRS_VISIBILITY 0x0001 ++ ++/* Header to define the PCIE specific capabilities in the extended config space */ ++typedef struct _pcie_enhanced_caphdr { ++ uint16 capID; ++ uint16 cap_ver : 4; ++ uint16 next_ptr : 12; ++} pcie_enhanced_caphdr; ++ ++ ++/* Everything below is BRCM HND proprietary */ ++ ++ ++/* Brcm PCI configuration registers */ ++#define cap_list rsvd_a[0] ++#define bar0_window dev_dep[0x80 - 0x40] ++#define bar1_window dev_dep[0x84 - 0x40] ++#define sprom_control dev_dep[0x88 - 0x40] ++#endif /* LINUX_POSTMOGRIFY_REMOVAL */ ++#define PCI_BAR0_WIN 0x80 /* backplane addres space accessed by BAR0 */ ++#define PCI_BAR1_WIN 0x84 /* backplane addres space accessed by BAR1 */ ++#define PCI_SPROM_CONTROL 0x88 /* sprom property control */ ++#define PCI_BAR1_CONTROL 0x8c /* BAR1 region burst control */ ++#define PCI_INT_STATUS 0x90 /* PCI and other cores interrupts */ ++#define PCI_INT_MASK 0x94 /* mask of PCI and other cores interrupts */ ++#define PCI_TO_SB_MB 0x98 /* signal backplane interrupts */ ++#define PCI_BACKPLANE_ADDR 0xa0 /* address an arbitrary location on the system backplane */ ++#define PCI_BACKPLANE_DATA 0xa4 /* data at the location specified by above address */ ++#define PCI_CLK_CTL_ST 0xa8 /* pci config space clock control/status (>=rev14) */ ++#define PCI_BAR0_WIN2 0xac /* backplane addres space accessed by second 4KB of BAR0 */ ++#define PCI_GPIO_IN 0xb0 /* pci config space gpio input (>=rev3) */ ++#define PCI_GPIO_OUT 0xb4 /* pci config space gpio output (>=rev3) */ ++#define PCI_GPIO_OUTEN 0xb8 /* pci config space gpio output enable (>=rev3) */ ++ ++#define PCI_BAR0_SHADOW_OFFSET (2 * 1024) /* bar0 + 2K accesses sprom shadow (in pci core) */ ++#define PCI_BAR0_SPROM_OFFSET (4 * 1024) /* bar0 + 4K accesses external sprom */ ++#define PCI_BAR0_PCIREGS_OFFSET (6 * 1024) /* bar0 + 6K accesses pci core registers */ ++#define PCI_BAR0_PCISBR_OFFSET (4 * 1024) /* pci core SB registers are at the end of the ++ * 8KB window, so their address is the "regular" ++ * address plus 4K ++ */ ++/* ++ * PCIE GEN2 changed some of the above locations for ++ * Bar0WrapperBase, SecondaryBAR0Window and SecondaryBAR0WrapperBase ++ * BAR0 maps 32K of register space ++*/ ++#define PCIE2_BAR0_WIN2 0x70 /* backplane addres space accessed by second 4KB of BAR0 */ ++#define PCIE2_BAR0_CORE2_WIN 0x74 /* backplane addres space accessed by second 4KB of BAR0 */ ++#define PCIE2_BAR0_CORE2_WIN2 0x78 /* backplane addres space accessed by second 4KB of BAR0 */ ++ ++#define PCI_BAR0_WINSZ (16 * 1024) /* bar0 window size Match with corerev 13 */ ++/* On pci corerev >= 13 and all pcie, the bar0 is now 16KB and it maps: */ ++#define PCI_16KB0_PCIREGS_OFFSET (8 * 1024) /* bar0 + 8K accesses pci/pcie core registers */ ++#define PCI_16KB0_CCREGS_OFFSET (12 * 1024) /* bar0 + 12K accesses chipc core registers */ ++#define PCI_16KBB0_WINSZ (16 * 1024) /* bar0 window size */ ++ ++#ifndef LINUX_POSTMOGRIFY_REMOVAL ++/* On AI chips we have a second window to map DMP regs are mapped: */ ++#define PCI_16KB0_WIN2_OFFSET (4 * 1024) /* bar0 + 4K is "Window 2" */ ++ ++/* PCI_INT_STATUS */ ++#define PCI_SBIM_STATUS_SERR 0x4 /* backplane SBErr interrupt status */ ++ ++/* PCI_INT_MASK */ ++#define PCI_SBIM_SHIFT 8 /* backplane core interrupt mask bits offset */ ++#define PCI_SBIM_MASK 0xff00 /* backplane core interrupt mask */ ++#define PCI_SBIM_MASK_SERR 0x4 /* backplane SBErr interrupt mask */ ++ ++#ifndef LINUX_POSTMOGRIFY_REMOVAL ++/* PCI_SPROM_CONTROL */ ++#define SPROM_SZ_MSK 0x02 /* SPROM Size Mask */ ++#define SPROM_LOCKED 0x08 /* SPROM Locked */ ++#define SPROM_BLANK 0x04 /* indicating a blank SPROM */ ++#define SPROM_WRITEEN 0x10 /* SPROM write enable */ ++#define SPROM_BOOTROM_WE 0x20 /* external bootrom write enable */ ++#define SPROM_BACKPLANE_EN 0x40 /* Enable indirect backplane access */ ++#define SPROM_OTPIN_USE 0x80 /* device OTP In use */ ++#endif /* LINUX_POSTMOGRIFY_REMOVAL */ ++ ++/* Bits in PCI command and status regs */ ++#define PCI_CMD_IO 0x00000001 /* I/O enable */ ++#define PCI_CMD_MEMORY 0x00000002 /* Memory enable */ ++#define PCI_CMD_MASTER 0x00000004 /* Master enable */ ++#define PCI_CMD_SPECIAL 0x00000008 /* Special cycles enable */ ++#define PCI_CMD_INVALIDATE 0x00000010 /* Invalidate? */ ++#define PCI_CMD_VGA_PAL 0x00000040 /* VGA Palate */ ++#define PCI_STAT_TA 0x08000000 /* target abort status */ ++#endif /* LINUX_POSTMOGRIFY_REMOVAL */ ++ ++#define PCI_CONFIG_SPACE_SIZE 256 ++#endif /* _h_pcicfg_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/phy542xx.h b/drivers/net/ethernet/broadcom/gmac/src/include/phy542xx.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/phy542xx.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/phy542xx.h 2017-11-09 17:53:43.973296000 +0800 +@@ -0,0 +1,98 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * These routines provide access to the external phy ++ * ++ */ ++ ++#ifndef _PHY542XX_H_ ++#define _PHY542XX_H_ ++ ++#include ++ ++/* Broadcom BCM542xx */ ++#define phy542xx_rd_reg phy542xx_reg_read ++#define phy542xx_wr_reg phy542xx_reg_write ++ ++#define BCM542XX_REG_EXP_SEL 0x17 ++#define BCM542XX_REG_EXP_SELECT_7E 0x0F7E ++#define BCM542XX_REG_EXP_DATA 0x15 ++#define BCM542XX_REG_EXP_RDB_EN 0x0000 ++ ++#define BCM542XX_REG_RDB_ADDR 0x1e ++#define BCM542XX_REG_RDB_DATA 0x1f ++ ++#define MIIM_BCM542xx_RDB_AUXSTATUS 0x09 ++#define MIIM_BCM542xx_AUXSTATUS_LINKMODE_MASK 0x0700 ++#define MIIM_BCM542xx_AUXSTATUS_LINKMODE_SHIFT 8 ++ ++#define BCM542XX_REG_RDB_MII_MISC_CTRL 0x02f ++ ++#define BCM542XX_REG_RDB_EXT_SERDES_CTRL 0x234 ++#define BCM542XX_REG_EXT_SERDES_AUTO_FX (1 << 6) ++#define BCM542XX_REG_EXT_SERDES_FX_FD (1 << 5) ++#define BCM542XX_REG_EXT_SERDES_FX (1 << 4) ++#define BCM542XX_REG_EXT_SERDES_LED (1 << 3) ++#define BCM542XX_REG_EXT_SEL_SYNC_ST (1 << 2) ++#define BCM542XX_REG_EXT_SELECT_SD (1 << 1) ++#define BCM542XX_REG_EXT_SERDES_SEL (1 << 0) ++#define BCM542XX_REG_EXT_SERDES_FX_MASK (BCM542XX_REG_EXT_SERDES_FX | \ ++ BCM542XX_REG_EXT_SERDES_AUTO_FX) ++ ++#define BCM542XX_REG_RDB_SGMII_SLAVE 0x235 ++#define BCM542XX_REG_SGMII_SLAVE_AUTO (1 << 0) ++ ++#define MIIM_BCM542xx_RDB_AUTO_DETECT_MEDIUM 0x23e ++#define BCM542XX_REG_MII_AUTO_DET_MED_2ND_SERDES (1 << 9) ++#define BCM542XX_REG_MII_INV_FIBER_SD (1 << 8) ++#define BCM542XX_REG_MII_FIBER_IN_USE_LED (1 << 7) ++#define BCM542XX_REG_MII_FIBER_LED (1 << 6) ++#define BCM542XX_REG_MII_FIBER_SD_SYNC (1 << 5) ++#define BCM542XX_REG_MII_FIBER_AUTO_PWRDN (1 << 4) ++#define BCM542XX_REG_MII_SD_en_ov (1 << 3) ++#define BCM542XX_REG_MII_AUTO_DET_MED_DEFAULT (1 << 2) ++#define BCM542XX_REG_MII_AUTO_DET_MED_PRI (1 << 1) ++#define BCM542XX_REG_MII_AUTO_DET_MED_EN (1 << 0) ++#define BCM542XX_REG_MII_AUTO_DET_MASK 0x033f ++ ++#define BCM542XX_REG_RDB_MODE_CTRL 0x021 ++#define BCM542XX_REG_MODE_CTRL_COPPER_LINK (1 << 7) ++#define BCM542XX_REG_MODE_CTRL_SERDES_LINK (1 << 6) ++#define BCM542XX_REG_MODE_CTRL_COPPER_ENERGY_DET (1 << 5) ++#define BCM542XX_REG_MODE_CNTL_MODE_SEL_2 (1 << 2) ++#define BCM542XX_REG_MODE_CNTL_MODE_SEL_1 (1 << 1) ++#define BCM542XX_REG_MODE_CTRL_1000X_EN (1 << 0) ++ ++#define BCM542XX_REG_RDB_COPPER_MISC_CTRL 0x02f ++#define BCM542XX_REG_MISC_CTRL_FORCE_AUTO_MDIX (1 << 9) ++ ++#define BCM542XX_REG_MODE_SEL_COPPER_2_SGMII (0x0) ++#define BCM542XX_REG_MODE_SEL_FIBER_2_SGMII (BCM542XX_REG_MODE_CNTL_MODE_SEL_1) ++#define BCM542XX_REG_MODE_SEL_SGMII_2_COPPER (BCM542XX_REG_MODE_CNTL_MODE_SEL_2) ++#define BCM542XX_REG_MODE_SEL_GBIC (BCM542XX_REG_MODE_CNTL_MODE_SEL_1 | \ ++ BCM542XX_REG_MODE_CNTL_MODE_SEL_2) ++ ++#define BCM542XX_REG_RDB_2ND_SERDES_BASE 0xb00 ++#define BCM542XX_REG_RDB_2ND_SERDES_MISC_1000X 0xb17 ++ ++ ++extern int phy542xx_reg_read(u32 phy_addr, u32 flags, int reg_addr, u16 *data); ++extern int phy542xx_reg_write(u32 phy_addr, u32 flags, int reg_addr, u16 data); ++extern int phy542xx_reset_setup(u32 phy_addr); ++extern int phy542xx_init(u32 phy_addr); ++extern int phy542xx_enable_set(u32 phy_addr, int enable); ++extern int phy542xx_force_auto_mdix(u32 phy_addr, int enable); ++ ++#endif /* _PHY542XX_H_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/proto/802.11.h b/drivers/net/ethernet/broadcom/gmac/src/include/proto/802.11.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/proto/802.11.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/proto/802.11.h 2017-11-09 17:53:43.976303000 +0800 +@@ -0,0 +1,2356 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Fundamental types and constants relating to 802.11 ++ * ++ * $Id: 802.11.h 308961 2012-01-18 03:01:00Z $ ++ */ ++ ++#ifndef _802_11_H_ ++#define _802_11_H_ ++ ++#ifndef _TYPEDEFS_H_ ++#include ++#endif ++ ++#ifndef _NET_ETHERNET_H_ ++#include ++#endif ++ ++#include ++ ++/* This marks the start of a packed structure section. */ ++#include ++ ++ ++#define DOT11_TU_TO_US 1024 /* 802.11 Time Unit is 1024 microseconds */ ++ ++/* Generic 802.11 frame constants */ ++#define DOT11_A3_HDR_LEN 24 /* d11 header length with A3 */ ++#define DOT11_A4_HDR_LEN 30 /* d11 header length with A4 */ ++#define DOT11_MAC_HDR_LEN DOT11_A3_HDR_LEN /* MAC header length */ ++#define DOT11_FCS_LEN 4 /* d11 FCS length */ ++#define DOT11_ICV_LEN 4 /* d11 ICV length */ ++#define DOT11_ICV_AES_LEN 8 /* d11 ICV/AES length */ ++#define DOT11_QOS_LEN 2 /* d11 QoS length */ ++#define DOT11_HTC_LEN 4 /* d11 HT Control field length */ ++ ++#define DOT11_KEY_INDEX_SHIFT 6 /* d11 key index shift */ ++#define DOT11_IV_LEN 4 /* d11 IV length */ ++#define DOT11_IV_TKIP_LEN 8 /* d11 IV TKIP length */ ++#define DOT11_IV_AES_OCB_LEN 4 /* d11 IV/AES/OCB length */ ++#define DOT11_IV_AES_CCM_LEN 8 /* d11 IV/AES/CCM length */ ++#define DOT11_IV_MAX_LEN 8 /* maximum iv len for any encryption */ ++ ++/* Includes MIC */ ++#define DOT11_MAX_MPDU_BODY_LEN 2304 /* max MPDU body length */ ++/* A4 header + QoS + CCMP + PDU + ICV + FCS = 2352 */ ++#define DOT11_MAX_MPDU_LEN (DOT11_A4_HDR_LEN + \ ++ DOT11_QOS_LEN + \ ++ DOT11_IV_AES_CCM_LEN + \ ++ DOT11_MAX_MPDU_BODY_LEN + \ ++ DOT11_ICV_LEN + \ ++ DOT11_FCS_LEN) /* d11 max MPDU length */ ++ ++#define DOT11_MAX_SSID_LEN 32 /* d11 max ssid length */ ++ ++/* dot11RTSThreshold */ ++#define DOT11_DEFAULT_RTS_LEN 2347 /* d11 default RTS length */ ++#define DOT11_MAX_RTS_LEN 2347 /* d11 max RTS length */ ++ ++/* dot11FragmentationThreshold */ ++#define DOT11_MIN_FRAG_LEN 256 /* d11 min fragmentation length */ ++#define DOT11_MAX_FRAG_LEN 2346 /* Max frag is also limited by aMPDUMaxLength ++ * of the attached PHY ++ */ ++#define DOT11_DEFAULT_FRAG_LEN 2346 /* d11 default fragmentation length */ ++ ++/* dot11BeaconPeriod */ ++#define DOT11_MIN_BEACON_PERIOD 1 /* d11 min beacon period */ ++#define DOT11_MAX_BEACON_PERIOD 0xFFFF /* d11 max beacon period */ ++ ++/* dot11DTIMPeriod */ ++#define DOT11_MIN_DTIM_PERIOD 1 /* d11 min DTIM period */ ++#define DOT11_MAX_DTIM_PERIOD 0xFF /* d11 max DTIM period */ ++ ++/* 802.2 LLC/SNAP header used by 802.11 per 802.1H */ ++#define DOT11_LLC_SNAP_HDR_LEN 8 /* d11 LLC/SNAP header length */ ++#define DOT11_OUI_LEN 3 /* d11 OUI length */ ++BWL_PRE_PACKED_STRUCT struct dot11_llc_snap_header { ++ uint8 dsap; /* always 0xAA */ ++ uint8 ssap; /* always 0xAA */ ++ uint8 ctl; /* always 0x03 */ ++ uint8 oui[DOT11_OUI_LEN]; /* RFC1042: 0x00 0x00 0x00 ++ * Bridge-Tunnel: 0x00 0x00 0xF8 ++ */ ++ uint16 type; /* ethertype */ ++} BWL_POST_PACKED_STRUCT; ++ ++/* RFC1042 header used by 802.11 per 802.1H */ ++#define RFC1042_HDR_LEN (ETHER_HDR_LEN + DOT11_LLC_SNAP_HDR_LEN) /* RCF1042 header length */ ++ ++/* Generic 802.11 MAC header */ ++/* ++ * N.B.: This struct reflects the full 4 address 802.11 MAC header. ++ * The fields are defined such that the shorter 1, 2, and 3 ++ * address headers just use the first k fields. ++ */ ++BWL_PRE_PACKED_STRUCT struct dot11_header { ++ uint16 fc; /* frame control */ ++ uint16 durid; /* duration/ID */ ++ struct ether_addr a1; /* address 1 */ ++ struct ether_addr a2; /* address 2 */ ++ struct ether_addr a3; /* address 3 */ ++ uint16 seq; /* sequence control */ ++ struct ether_addr a4; /* address 4 */ ++} BWL_POST_PACKED_STRUCT; ++ ++/* Control frames */ ++ ++BWL_PRE_PACKED_STRUCT struct dot11_rts_frame { ++ uint16 fc; /* frame control */ ++ uint16 durid; /* duration/ID */ ++ struct ether_addr ra; /* receiver address */ ++ struct ether_addr ta; /* transmitter address */ ++} BWL_POST_PACKED_STRUCT; ++#define DOT11_RTS_LEN 16 /* d11 RTS frame length */ ++ ++BWL_PRE_PACKED_STRUCT struct dot11_cts_frame { ++ uint16 fc; /* frame control */ ++ uint16 durid; /* duration/ID */ ++ struct ether_addr ra; /* receiver address */ ++} BWL_POST_PACKED_STRUCT; ++#define DOT11_CTS_LEN 10 /* d11 CTS frame length */ ++ ++BWL_PRE_PACKED_STRUCT struct dot11_ack_frame { ++ uint16 fc; /* frame control */ ++ uint16 durid; /* duration/ID */ ++ struct ether_addr ra; /* receiver address */ ++} BWL_POST_PACKED_STRUCT; ++#define DOT11_ACK_LEN 10 /* d11 ACK frame length */ ++ ++BWL_PRE_PACKED_STRUCT struct dot11_ps_poll_frame { ++ uint16 fc; /* frame control */ ++ uint16 durid; /* AID */ ++ struct ether_addr bssid; /* receiver address, STA in AP */ ++ struct ether_addr ta; /* transmitter address */ ++} BWL_POST_PACKED_STRUCT; ++#define DOT11_PS_POLL_LEN 16 /* d11 PS poll frame length */ ++ ++BWL_PRE_PACKED_STRUCT struct dot11_cf_end_frame { ++ uint16 fc; /* frame control */ ++ uint16 durid; /* duration/ID */ ++ struct ether_addr ra; /* receiver address */ ++ struct ether_addr bssid; /* transmitter address, STA in AP */ ++} BWL_POST_PACKED_STRUCT; ++#define DOT11_CS_END_LEN 16 /* d11 CF-END frame length */ ++ ++/* RWL wifi protocol: The Vendor Specific Action frame is defined for vendor-specific signaling ++* category+OUI+vendor specific content ( this can be variable) ++*/ ++BWL_PRE_PACKED_STRUCT struct dot11_action_wifi_vendor_specific { ++ uint8 category; ++ uint8 OUI[3]; ++ uint8 type; ++ uint8 subtype; ++ uint8 data[1040]; ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_action_wifi_vendor_specific dot11_action_wifi_vendor_specific_t; ++ ++/* generic vender specific action frame with variable length */ ++BWL_PRE_PACKED_STRUCT struct dot11_action_vs_frmhdr { ++ uint8 category; ++ uint8 OUI[3]; ++ uint8 type; ++ uint8 subtype; ++ uint8 data[1]; ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_action_vs_frmhdr dot11_action_vs_frmhdr_t; ++#define DOT11_ACTION_VS_HDR_LEN 6 ++ ++#define BCM_ACTION_OUI_BYTE0 0x00 ++#define BCM_ACTION_OUI_BYTE1 0x90 ++#define BCM_ACTION_OUI_BYTE2 0x4c ++ ++/* BA/BAR Control parameters */ ++#define DOT11_BA_CTL_POLICY_NORMAL 0x0000 /* normal ack */ ++#define DOT11_BA_CTL_POLICY_NOACK 0x0001 /* no ack */ ++#define DOT11_BA_CTL_POLICY_MASK 0x0001 /* ack policy mask */ ++ ++#define DOT11_BA_CTL_MTID 0x0002 /* multi tid BA */ ++#define DOT11_BA_CTL_COMPRESSED 0x0004 /* compressed bitmap */ ++ ++#define DOT11_BA_CTL_NUMMSDU_MASK 0x0FC0 /* num msdu in bitmap mask */ ++#define DOT11_BA_CTL_NUMMSDU_SHIFT 6 /* num msdu in bitmap shift */ ++ ++#define DOT11_BA_CTL_TID_MASK 0xF000 /* tid mask */ ++#define DOT11_BA_CTL_TID_SHIFT 12 /* tid shift */ ++ ++/* control frame header (BA/BAR) */ ++BWL_PRE_PACKED_STRUCT struct dot11_ctl_header { ++ uint16 fc; /* frame control */ ++ uint16 durid; /* duration/ID */ ++ struct ether_addr ra; /* receiver address */ ++ struct ether_addr ta; /* transmitter address */ ++} BWL_POST_PACKED_STRUCT; ++#define DOT11_CTL_HDR_LEN 16 /* control frame hdr len */ ++ ++/* BAR frame payload */ ++BWL_PRE_PACKED_STRUCT struct dot11_bar { ++ uint16 bar_control; /* BAR Control */ ++ uint16 seqnum; /* Starting Sequence control */ ++} BWL_POST_PACKED_STRUCT; ++#define DOT11_BAR_LEN 4 /* BAR frame payload length */ ++ ++#define DOT11_BA_BITMAP_LEN 128 /* bitmap length */ ++#define DOT11_BA_CMP_BITMAP_LEN 8 /* compressed bitmap length */ ++/* BA frame payload */ ++BWL_PRE_PACKED_STRUCT struct dot11_ba { ++ uint16 ba_control; /* BA Control */ ++ uint16 seqnum; /* Starting Sequence control */ ++ uint8 bitmap[DOT11_BA_BITMAP_LEN]; /* Block Ack Bitmap */ ++} BWL_POST_PACKED_STRUCT; ++#define DOT11_BA_LEN 4 /* BA frame payload len (wo bitmap) */ ++ ++/* Management frame header */ ++BWL_PRE_PACKED_STRUCT struct dot11_management_header { ++ uint16 fc; /* frame control */ ++ uint16 durid; /* duration/ID */ ++ struct ether_addr da; /* receiver address */ ++ struct ether_addr sa; /* transmitter address */ ++ struct ether_addr bssid; /* BSS ID */ ++ uint16 seq; /* sequence control */ ++} BWL_POST_PACKED_STRUCT; ++#define DOT11_MGMT_HDR_LEN 24 /* d11 management header length */ ++ ++/* Management frame payloads */ ++ ++BWL_PRE_PACKED_STRUCT struct dot11_bcn_prb { ++ uint32 timestamp[2]; ++ uint16 beacon_interval; ++ uint16 capability; ++} BWL_POST_PACKED_STRUCT; ++#define DOT11_BCN_PRB_LEN 12 /* 802.11 beacon/probe frame fixed length */ ++#define DOT11_BCN_PRB_FIXED_LEN 12 /* 802.11 beacon/probe frame fixed length */ ++ ++BWL_PRE_PACKED_STRUCT struct dot11_auth { ++ uint16 alg; /* algorithm */ ++ uint16 seq; /* sequence control */ ++ uint16 status; /* status code */ ++} BWL_POST_PACKED_STRUCT; ++#define DOT11_AUTH_FIXED_LEN 6 /* length of auth frame without challenge IE */ ++ ++BWL_PRE_PACKED_STRUCT struct dot11_assoc_req { ++ uint16 capability; /* capability information */ ++ uint16 listen; /* listen interval */ ++} BWL_POST_PACKED_STRUCT; ++#define DOT11_ASSOC_REQ_FIXED_LEN 4 /* length of assoc frame without info elts */ ++ ++BWL_PRE_PACKED_STRUCT struct dot11_reassoc_req { ++ uint16 capability; /* capability information */ ++ uint16 listen; /* listen interval */ ++ struct ether_addr ap; /* Current AP address */ ++} BWL_POST_PACKED_STRUCT; ++#define DOT11_REASSOC_REQ_FIXED_LEN 10 /* length of assoc frame without info elts */ ++ ++BWL_PRE_PACKED_STRUCT struct dot11_assoc_resp { ++ uint16 capability; /* capability information */ ++ uint16 status; /* status code */ ++ uint16 aid; /* association ID */ ++} BWL_POST_PACKED_STRUCT; ++#define DOT11_ASSOC_RESP_FIXED_LEN 6 /* length of assoc resp frame without info elts */ ++ ++BWL_PRE_PACKED_STRUCT struct dot11_action_measure { ++ uint8 category; ++ uint8 action; ++ uint8 token; ++ uint8 data[1]; ++} BWL_POST_PACKED_STRUCT; ++#define DOT11_ACTION_MEASURE_LEN 3 /* d11 action measurement header length */ ++ ++BWL_PRE_PACKED_STRUCT struct dot11_action_ht_ch_width { ++ uint8 category; ++ uint8 action; ++ uint8 ch_width; ++} BWL_POST_PACKED_STRUCT; ++ ++BWL_PRE_PACKED_STRUCT struct dot11_action_ht_mimops { ++ uint8 category; ++ uint8 action; ++ uint8 control; ++} BWL_POST_PACKED_STRUCT; ++ ++BWL_PRE_PACKED_STRUCT struct dot11_action_sa_query { ++ uint8 category; ++ uint8 action; ++ uint16 id; ++} BWL_POST_PACKED_STRUCT; ++ ++#define SM_PWRSAVE_ENABLE 1 ++#define SM_PWRSAVE_MODE 2 ++ ++/* ************* 802.11h related definitions. ************* */ ++BWL_PRE_PACKED_STRUCT struct dot11_power_cnst { ++ uint8 id; ++ uint8 len; ++ uint8 power; ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_power_cnst dot11_power_cnst_t; ++ ++BWL_PRE_PACKED_STRUCT struct dot11_power_cap { ++ uint8 min; ++ uint8 max; ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_power_cap dot11_power_cap_t; ++ ++BWL_PRE_PACKED_STRUCT struct dot11_tpc_rep { ++ uint8 id; ++ uint8 len; ++ uint8 tx_pwr; ++ uint8 margin; ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_tpc_rep dot11_tpc_rep_t; ++#define DOT11_MNG_IE_TPC_REPORT_LEN 2 /* length of IE data, not including 2 byte header */ ++ ++BWL_PRE_PACKED_STRUCT struct dot11_supp_channels { ++ uint8 id; ++ uint8 len; ++ uint8 first_channel; ++ uint8 num_channels; ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_supp_channels dot11_supp_channels_t; ++ ++/* Extension Channel Offset IE: 802.11n-D1.0 spec. added sideband ++ * offset for 40MHz operation. The possible 3 values are: ++ * 1 = above control channel ++ * 3 = below control channel ++ * 0 = no extension channel ++ */ ++BWL_PRE_PACKED_STRUCT struct dot11_extch { ++ uint8 id; /* IE ID, 62, DOT11_MNG_EXT_CHANNEL_OFFSET */ ++ uint8 len; /* IE length */ ++ uint8 extch; ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_extch dot11_extch_ie_t; ++ ++BWL_PRE_PACKED_STRUCT struct dot11_brcm_extch { ++ uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */ ++ uint8 len; /* IE length */ ++ uint8 oui[3]; /* Proprietary OUI, BRCM_PROP_OUI */ ++ uint8 type; /* type inidicates what follows */ ++ uint8 extch; ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_brcm_extch dot11_brcm_extch_ie_t; ++ ++#define BRCM_EXTCH_IE_LEN 5 ++#define BRCM_EXTCH_IE_TYPE 53 /* 802.11n ID not yet assigned */ ++#define DOT11_EXTCH_IE_LEN 1 ++#define DOT11_EXT_CH_MASK 0x03 /* extension channel mask */ ++#define DOT11_EXT_CH_UPPER 0x01 /* ext. ch. on upper sb */ ++#define DOT11_EXT_CH_LOWER 0x03 /* ext. ch. on lower sb */ ++#define DOT11_EXT_CH_NONE 0x00 /* no extension ch. */ ++ ++BWL_PRE_PACKED_STRUCT struct dot11_action_frmhdr { ++ uint8 category; ++ uint8 action; ++ uint8 data[1]; ++} BWL_POST_PACKED_STRUCT; ++#define DOT11_ACTION_FRMHDR_LEN 2 ++ ++/* CSA IE data structure */ ++BWL_PRE_PACKED_STRUCT struct dot11_channel_switch { ++ uint8 id; /* id DOT11_MNG_CHANNEL_SWITCH_ID */ ++ uint8 len; /* length of IE */ ++ uint8 mode; /* mode 0 or 1 */ ++ uint8 channel; /* channel switch to */ ++ uint8 count; /* number of beacons before switching */ ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_channel_switch dot11_chan_switch_ie_t; ++ ++#define DOT11_SWITCH_IE_LEN 3 /* length of IE data, not including 2 byte header */ ++/* CSA mode - 802.11h-2003 $7.3.2.20 */ ++#define DOT11_CSA_MODE_ADVISORY 0 /* no DOT11_CSA_MODE_NO_TX restriction imposed */ ++#define DOT11_CSA_MODE_NO_TX 1 /* no transmission upon receiving CSA frame. */ ++ ++BWL_PRE_PACKED_STRUCT struct dot11_action_switch_channel { ++ uint8 category; ++ uint8 action; ++ dot11_chan_switch_ie_t chan_switch_ie; /* for switch IE */ ++ dot11_brcm_extch_ie_t extch_ie; /* extension channel offset */ ++} BWL_POST_PACKED_STRUCT; ++ ++BWL_PRE_PACKED_STRUCT struct dot11_csa_body { ++ uint8 mode; /* mode 0 or 1 */ ++ uint8 reg; /* regulatory class */ ++ uint8 channel; /* channel switch to */ ++ uint8 count; /* number of beacons before switching */ ++} BWL_POST_PACKED_STRUCT; ++ ++/* 11n Extended Channel Switch IE data structure */ ++BWL_PRE_PACKED_STRUCT struct dot11_ext_csa { ++ uint8 id; /* id DOT11_MNG_EXT_CHANNEL_SWITCH_ID */ ++ uint8 len; /* length of IE */ ++ struct dot11_csa_body b; /* body of the ie */ ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_ext_csa dot11_ext_csa_ie_t; ++#define DOT11_EXT_CSA_IE_LEN 4 /* length of extended channel switch IE body */ ++ ++BWL_PRE_PACKED_STRUCT struct dot11_action_ext_csa { ++ uint8 category; ++ uint8 action; ++ dot11_ext_csa_ie_t chan_switch_ie; /* for switch IE */ ++} BWL_POST_PACKED_STRUCT; ++ ++BWL_PRE_PACKED_STRUCT struct dot11y_action_ext_csa { ++ uint8 category; ++ uint8 action; ++ struct dot11_csa_body b; /* body of the ie */ ++} BWL_POST_PACKED_STRUCT; ++ ++BWL_PRE_PACKED_STRUCT struct dot11_obss_coex { ++ uint8 id; ++ uint8 len; ++ uint8 info; ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_obss_coex dot11_obss_coex_t; ++#define DOT11_OBSS_COEXINFO_LEN 1 /* length of OBSS Coexistence INFO IE */ ++ ++#define DOT11_OBSS_COEX_INFO_REQ 0x01 ++#define DOT11_OBSS_COEX_40MHZ_INTOLERANT 0x02 ++#define DOT11_OBSS_COEX_20MHZ_WIDTH_REQ 0x04 ++ ++BWL_PRE_PACKED_STRUCT struct dot11_obss_chanlist { ++ uint8 id; ++ uint8 len; ++ uint8 regclass; ++ uint8 chanlist[1]; ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_obss_chanlist dot11_obss_chanlist_t; ++#define DOT11_OBSS_CHANLIST_FIXED_LEN 1 /* fixed length of regclass */ ++ ++BWL_PRE_PACKED_STRUCT struct dot11_extcap_ie { ++ uint8 id; ++ uint8 len; ++ uint8 cap[1]; ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_extcap_ie dot11_extcap_ie_t; ++ ++#define DOT11_EXTCAP_LEN_MAX 7 ++#define DOT11_EXTCAP_LEN_COEX 1 ++#define DOT11_EXTCAP_LEN_BT 3 ++#define DOT11_EXTCAP_LEN_IW 4 ++#define DOT11_EXTCAP_LEN_SI 6 ++ ++#define DOT11_EXTCAP_LEN_TDLS 5 ++BWL_PRE_PACKED_STRUCT struct dot11_extcap { ++ uint8 extcap[DOT11_EXTCAP_LEN_TDLS]; ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_extcap dot11_extcap_t; ++ ++/* TDLS Capabilities */ ++#define TDLS_CAP_TDLS 37 /* TDLS support */ ++#define TDLS_CAP_PU_BUFFER_STA 28 /* TDLS Peer U-APSD buffer STA support */ ++#define TDLS_CAP_PEER_PSM 20 /* TDLS Peer PSM support */ ++#define TDLS_CAP_CH_SW 30 /* TDLS Channel switch */ ++#define TDLS_CAP_PROH 38 /* TDLS prohibited */ ++#define TDLS_CAP_CH_SW_PROH 39 /* TDLS Channel switch prohibited */ ++ ++#define TDLS_CAP_MAX_BIT 39 /* TDLS max bit defined in ext cap */ ++ ++/* 802.11h/802.11k Measurement Request/Report IEs */ ++/* Measurement Type field */ ++#define DOT11_MEASURE_TYPE_BASIC 0 /* d11 measurement basic type */ ++#define DOT11_MEASURE_TYPE_CCA 1 /* d11 measurement CCA type */ ++#define DOT11_MEASURE_TYPE_RPI 2 /* d11 measurement RPI type */ ++#define DOT11_MEASURE_TYPE_CHLOAD 3 /* d11 measurement Channel Load type */ ++#define DOT11_MEASURE_TYPE_NOISE 4 /* d11 measurement Noise Histogram type */ ++#define DOT11_MEASURE_TYPE_BEACON 5 /* d11 measurement Beacon type */ ++#define DOT11_MEASURE_TYPE_FRAME 6 /* d11 measurement Frame type */ ++#define DOT11_MEASURE_TYPE_STATS 7 /* d11 measurement STA Statistics type */ ++#define DOT11_MEASURE_TYPE_LCI 8 /* d11 measurement LCI type */ ++#define DOT11_MEASURE_TYPE_TXSTREAM 9 /* d11 measurement TX Stream type */ ++#define DOT11_MEASURE_TYPE_PAUSE 255 /* d11 measurement pause type */ ++ ++/* Measurement Request Modes */ ++#define DOT11_MEASURE_MODE_PARALLEL (1<<0) /* d11 measurement parallel */ ++#define DOT11_MEASURE_MODE_ENABLE (1<<1) /* d11 measurement enable */ ++#define DOT11_MEASURE_MODE_REQUEST (1<<2) /* d11 measurement request */ ++#define DOT11_MEASURE_MODE_REPORT (1<<3) /* d11 measurement report */ ++#define DOT11_MEASURE_MODE_DUR (1<<4) /* d11 measurement dur mandatory */ ++/* Measurement Report Modes */ ++#define DOT11_MEASURE_MODE_LATE (1<<0) /* d11 measurement late */ ++#define DOT11_MEASURE_MODE_INCAPABLE (1<<1) /* d11 measurement incapable */ ++#define DOT11_MEASURE_MODE_REFUSED (1<<2) /* d11 measurement refuse */ ++/* Basic Measurement Map bits */ ++#define DOT11_MEASURE_BASIC_MAP_BSS ((uint8)(1<<0)) /* d11 measurement basic map BSS */ ++#define DOT11_MEASURE_BASIC_MAP_OFDM ((uint8)(1<<1)) /* d11 measurement map OFDM */ ++#define DOT11_MEASURE_BASIC_MAP_UKNOWN ((uint8)(1<<2)) /* d11 measurement map unknown */ ++#define DOT11_MEASURE_BASIC_MAP_RADAR ((uint8)(1<<3)) /* d11 measurement map radar */ ++#define DOT11_MEASURE_BASIC_MAP_UNMEAS ((uint8)(1<<4)) /* d11 measurement map unmeasuremnt */ ++ ++BWL_PRE_PACKED_STRUCT struct dot11_meas_req { ++ uint8 id; ++ uint8 len; ++ uint8 token; ++ uint8 mode; ++ uint8 type; ++ uint8 channel; ++ uint8 start_time[8]; ++ uint16 duration; ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_meas_req dot11_meas_req_t; ++#define DOT11_MNG_IE_MREQ_LEN 14 /* d11 measurement request IE length */ ++/* length of Measure Request IE data not including variable len */ ++#define DOT11_MNG_IE_MREQ_FIXED_LEN 3 /* d11 measurement request IE fixed length */ ++ ++BWL_PRE_PACKED_STRUCT struct dot11_meas_rep { ++ uint8 id; ++ uint8 len; ++ uint8 token; ++ uint8 mode; ++ uint8 type; ++ BWL_PRE_PACKED_STRUCT union ++ { ++ BWL_PRE_PACKED_STRUCT struct { ++ uint8 channel; ++ uint8 start_time[8]; ++ uint16 duration; ++ uint8 map; ++ } BWL_POST_PACKED_STRUCT basic; ++ uint8 data[1]; ++ } BWL_POST_PACKED_STRUCT rep; ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_meas_rep dot11_meas_rep_t; ++ ++/* length of Measure Report IE data not including variable len */ ++#define DOT11_MNG_IE_MREP_FIXED_LEN 3 /* d11 measurement response IE fixed length */ ++ ++BWL_PRE_PACKED_STRUCT struct dot11_meas_rep_basic { ++ uint8 channel; ++ uint8 start_time[8]; ++ uint16 duration; ++ uint8 map; ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_meas_rep_basic dot11_meas_rep_basic_t; ++#define DOT11_MEASURE_BASIC_REP_LEN 12 /* d11 measurement basic report length */ ++ ++BWL_PRE_PACKED_STRUCT struct dot11_quiet { ++ uint8 id; ++ uint8 len; ++ uint8 count; /* TBTTs until beacon interval in quiet starts */ ++ uint8 period; /* Beacon intervals between periodic quiet periods ? */ ++ uint16 duration; /* Length of quiet period, in TU's */ ++ uint16 offset; /* TU's offset from TBTT in Count field */ ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_quiet dot11_quiet_t; ++ ++BWL_PRE_PACKED_STRUCT struct chan_map_tuple { ++ uint8 channel; ++ uint8 map; ++} BWL_POST_PACKED_STRUCT; ++typedef struct chan_map_tuple chan_map_tuple_t; ++ ++BWL_PRE_PACKED_STRUCT struct dot11_ibss_dfs { ++ uint8 id; ++ uint8 len; ++ uint8 eaddr[ETHER_ADDR_LEN]; ++ uint8 interval; ++ chan_map_tuple_t map[1]; ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_ibss_dfs dot11_ibss_dfs_t; ++ ++/* WME Elements */ ++#define WME_OUI "\x00\x50\xf2" /* WME OUI */ ++#define WME_OUI_LEN 3 ++#define WME_OUI_TYPE 2 /* WME type */ ++#define WME_TYPE 2 /* WME type, deprecated */ ++#define WME_SUBTYPE_IE 0 /* Information Element */ ++#define WME_SUBTYPE_PARAM_IE 1 /* Parameter Element */ ++#define WME_SUBTYPE_TSPEC 2 /* Traffic Specification */ ++#define WME_VER 1 /* WME version */ ++ ++/* WME Access Category Indices (ACIs) */ ++#define AC_BE 0 /* Best Effort */ ++#define AC_BK 1 /* Background */ ++#define AC_VI 2 /* Video */ ++#define AC_VO 3 /* Voice */ ++#define AC_COUNT 4 /* number of ACs */ ++ ++typedef uint8 ac_bitmap_t; /* AC bitmap of (1 << AC_xx) */ ++ ++#define AC_BITMAP_NONE 0x0 /* No ACs */ ++#define AC_BITMAP_ALL 0xf /* All ACs */ ++#define AC_BITMAP_TST(ab, ac) (((ab) & (1 << (ac))) != 0) ++#define AC_BITMAP_SET(ab, ac) (((ab) |= (1 << (ac)))) ++#define AC_BITMAP_RESET(ab, ac) (((ab) &= ~(1 << (ac)))) ++ ++/* WME Information Element (IE) */ ++BWL_PRE_PACKED_STRUCT struct wme_ie { ++ uint8 oui[3]; ++ uint8 type; ++ uint8 subtype; ++ uint8 version; ++ uint8 qosinfo; ++} BWL_POST_PACKED_STRUCT; ++typedef struct wme_ie wme_ie_t; ++#define WME_IE_LEN 7 /* WME IE length */ ++ ++BWL_PRE_PACKED_STRUCT struct edcf_acparam { ++ uint8 ACI; ++ uint8 ECW; ++ uint16 TXOP; /* stored in network order (ls octet first) */ ++} BWL_POST_PACKED_STRUCT; ++typedef struct edcf_acparam edcf_acparam_t; ++ ++/* WME Parameter Element (PE) */ ++BWL_PRE_PACKED_STRUCT struct wme_param_ie { ++ uint8 oui[3]; ++ uint8 type; ++ uint8 subtype; ++ uint8 version; ++ uint8 qosinfo; ++ uint8 rsvd; ++ edcf_acparam_t acparam[AC_COUNT]; ++} BWL_POST_PACKED_STRUCT; ++typedef struct wme_param_ie wme_param_ie_t; ++#define WME_PARAM_IE_LEN 24 /* WME Parameter IE length */ ++ ++/* QoS Info field for IE as sent from AP */ ++#define WME_QI_AP_APSD_MASK 0x80 /* U-APSD Supported mask */ ++#define WME_QI_AP_APSD_SHIFT 7 /* U-APSD Supported shift */ ++#define WME_QI_AP_COUNT_MASK 0x0f /* Parameter set count mask */ ++#define WME_QI_AP_COUNT_SHIFT 0 /* Parameter set count shift */ ++ ++/* QoS Info field for IE as sent from STA */ ++#define WME_QI_STA_MAXSPLEN_MASK 0x60 /* Max Service Period Length mask */ ++#define WME_QI_STA_MAXSPLEN_SHIFT 5 /* Max Service Period Length shift */ ++#define WME_QI_STA_APSD_ALL_MASK 0xf /* APSD all AC bits mask */ ++#define WME_QI_STA_APSD_ALL_SHIFT 0 /* APSD all AC bits shift */ ++#define WME_QI_STA_APSD_BE_MASK 0x8 /* APSD AC_BE mask */ ++#define WME_QI_STA_APSD_BE_SHIFT 3 /* APSD AC_BE shift */ ++#define WME_QI_STA_APSD_BK_MASK 0x4 /* APSD AC_BK mask */ ++#define WME_QI_STA_APSD_BK_SHIFT 2 /* APSD AC_BK shift */ ++#define WME_QI_STA_APSD_VI_MASK 0x2 /* APSD AC_VI mask */ ++#define WME_QI_STA_APSD_VI_SHIFT 1 /* APSD AC_VI shift */ ++#define WME_QI_STA_APSD_VO_MASK 0x1 /* APSD AC_VO mask */ ++#define WME_QI_STA_APSD_VO_SHIFT 0 /* APSD AC_VO shift */ ++ ++/* ACI */ ++#define EDCF_AIFSN_MIN 1 /* AIFSN minimum value */ ++#define EDCF_AIFSN_MAX 15 /* AIFSN maximum value */ ++#define EDCF_AIFSN_MASK 0x0f /* AIFSN mask */ ++#define EDCF_ACM_MASK 0x10 /* ACM mask */ ++#define EDCF_ACI_MASK 0x60 /* ACI mask */ ++#define EDCF_ACI_SHIFT 5 /* ACI shift */ ++#define EDCF_AIFSN_SHIFT 12 /* 4 MSB(0xFFF) in ifs_ctl for AC idx */ ++ ++/* ECW */ ++#define EDCF_ECW_MIN 0 /* cwmin/cwmax exponent minimum value */ ++#define EDCF_ECW_MAX 15 /* cwmin/cwmax exponent maximum value */ ++#define EDCF_ECW2CW(exp) ((1 << (exp)) - 1) ++#define EDCF_ECWMIN_MASK 0x0f /* cwmin exponent form mask */ ++#define EDCF_ECWMAX_MASK 0xf0 /* cwmax exponent form mask */ ++#define EDCF_ECWMAX_SHIFT 4 /* cwmax exponent form shift */ ++ ++/* TXOP */ ++#define EDCF_TXOP_MIN 0 /* TXOP minimum value */ ++#define EDCF_TXOP_MAX 65535 /* TXOP maximum value */ ++#define EDCF_TXOP2USEC(txop) ((txop) << 5) ++ ++/* Default BE ACI value for non-WME connection STA */ ++#define NON_EDCF_AC_BE_ACI_STA 0x02 ++ ++/* Default EDCF parameters that AP advertises for STA to use; WMM draft Table 12 */ ++#define EDCF_AC_BE_ACI_STA 0x03 /* STA ACI value for best effort AC */ ++#define EDCF_AC_BE_ECW_STA 0xA4 /* STA ECW value for best effort AC */ ++#define EDCF_AC_BE_TXOP_STA 0x0000 /* STA TXOP value for best effort AC */ ++#define EDCF_AC_BK_ACI_STA 0x27 /* STA ACI value for background AC */ ++#define EDCF_AC_BK_ECW_STA 0xA4 /* STA ECW value for background AC */ ++#define EDCF_AC_BK_TXOP_STA 0x0000 /* STA TXOP value for background AC */ ++#define EDCF_AC_VI_ACI_STA 0x42 /* STA ACI value for video AC */ ++#define EDCF_AC_VI_ECW_STA 0x43 /* STA ECW value for video AC */ ++#define EDCF_AC_VI_TXOP_STA 0x005e /* STA TXOP value for video AC */ ++#define EDCF_AC_VO_ACI_STA 0x62 /* STA ACI value for audio AC */ ++#define EDCF_AC_VO_ECW_STA 0x32 /* STA ECW value for audio AC */ ++#define EDCF_AC_VO_TXOP_STA 0x002f /* STA TXOP value for audio AC */ ++ ++/* Default EDCF parameters that AP uses; WMM draft Table 14 */ ++#define EDCF_AC_BE_ACI_AP 0x03 /* AP ACI value for best effort AC */ ++#define EDCF_AC_BE_ECW_AP 0x64 /* AP ECW value for best effort AC */ ++#define EDCF_AC_BE_TXOP_AP 0x0000 /* AP TXOP value for best effort AC */ ++#define EDCF_AC_BK_ACI_AP 0x27 /* AP ACI value for background AC */ ++#define EDCF_AC_BK_ECW_AP 0xA4 /* AP ECW value for background AC */ ++#define EDCF_AC_BK_TXOP_AP 0x0000 /* AP TXOP value for background AC */ ++#define EDCF_AC_VI_ACI_AP 0x41 /* AP ACI value for video AC */ ++#define EDCF_AC_VI_ECW_AP 0x43 /* AP ECW value for video AC */ ++#define EDCF_AC_VI_TXOP_AP 0x005e /* AP TXOP value for video AC */ ++#define EDCF_AC_VO_ACI_AP 0x61 /* AP ACI value for audio AC */ ++#define EDCF_AC_VO_ECW_AP 0x32 /* AP ECW value for audio AC */ ++#define EDCF_AC_VO_TXOP_AP 0x002f /* AP TXOP value for audio AC */ ++ ++/* EDCA Parameter IE */ ++BWL_PRE_PACKED_STRUCT struct edca_param_ie { ++ uint8 qosinfo; ++ uint8 rsvd; ++ edcf_acparam_t acparam[AC_COUNT]; ++} BWL_POST_PACKED_STRUCT; ++typedef struct edca_param_ie edca_param_ie_t; ++#define EDCA_PARAM_IE_LEN 18 /* EDCA Parameter IE length */ ++ ++/* QoS Capability IE */ ++BWL_PRE_PACKED_STRUCT struct qos_cap_ie { ++ uint8 qosinfo; ++} BWL_POST_PACKED_STRUCT; ++typedef struct qos_cap_ie qos_cap_ie_t; ++ ++BWL_PRE_PACKED_STRUCT struct dot11_qbss_load_ie { ++ uint8 id; /* 11, DOT11_MNG_QBSS_LOAD_ID */ ++ uint8 length; ++ uint16 station_count; /* total number of STAs associated */ ++ uint8 channel_utilization; /* % of time, normalized to 255, QAP sensed medium busy */ ++ uint16 aac; /* available admission capacity */ ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_qbss_load_ie dot11_qbss_load_ie_t; ++#define BSS_LOAD_IE_SIZE 7 /* BSS load IE size */ ++ ++/* nom_msdu_size */ ++#define FIXED_MSDU_SIZE 0x8000 /* MSDU size is fixed */ ++#define MSDU_SIZE_MASK 0x7fff /* (Nominal or fixed) MSDU size */ ++ ++/* surplus_bandwidth */ ++/* Represented as 3 bits of integer, binary point, 13 bits fraction */ ++#define INTEGER_SHIFT 13 /* integer shift */ ++#define FRACTION_MASK 0x1FFF /* fraction mask */ ++ ++/* Management Notification Frame */ ++BWL_PRE_PACKED_STRUCT struct dot11_management_notification { ++ uint8 category; /* DOT11_ACTION_NOTIFICATION */ ++ uint8 action; ++ uint8 token; ++ uint8 status; ++ uint8 data[1]; /* Elements */ ++} BWL_POST_PACKED_STRUCT; ++#define DOT11_MGMT_NOTIFICATION_LEN 4 /* Fixed length */ ++ ++/* Timeout Interval IE */ ++BWL_PRE_PACKED_STRUCT struct ti_ie { ++ uint8 ti_type; ++ uint32 ti_val; ++} BWL_POST_PACKED_STRUCT; ++typedef struct ti_ie ti_ie_t; ++#define TI_TYPE_REASSOC_DEADLINE 1 ++#define TI_TYPE_KEY_LIFETIME 2 ++ ++/* WME Action Codes */ ++#define WME_ADDTS_REQUEST 0 /* WME ADDTS request */ ++#define WME_ADDTS_RESPONSE 1 /* WME ADDTS response */ ++#define WME_DELTS_REQUEST 2 /* WME DELTS request */ ++ ++/* WME Setup Response Status Codes */ ++#define WME_ADMISSION_ACCEPTED 0 /* WME admission accepted */ ++#define WME_INVALID_PARAMETERS 1 /* WME invalide parameters */ ++#define WME_ADMISSION_REFUSED 3 /* WME admission refused */ ++ ++/* Macro to take a pointer to a beacon or probe response ++ * body and return the char* pointer to the SSID info element ++ */ ++#define BCN_PRB_SSID(body) ((char*)(body) + DOT11_BCN_PRB_LEN) ++ ++/* Authentication frame payload constants */ ++#define DOT11_OPEN_SYSTEM 0 /* d11 open authentication */ ++#define DOT11_SHARED_KEY 1 /* d11 shared authentication */ ++#define DOT11_FAST_BSS 2 /* d11 fast bss authentication */ ++#define DOT11_CHALLENGE_LEN 128 /* d11 challenge text length */ ++ ++/* Frame control macros */ ++#define FC_PVER_MASK 0x3 /* PVER mask */ ++#define FC_PVER_SHIFT 0 /* PVER shift */ ++#define FC_TYPE_MASK 0xC /* type mask */ ++#define FC_TYPE_SHIFT 2 /* type shift */ ++#define FC_SUBTYPE_MASK 0xF0 /* subtype mask */ ++#define FC_SUBTYPE_SHIFT 4 /* subtype shift */ ++#define FC_TODS 0x100 /* to DS */ ++#define FC_TODS_SHIFT 8 /* to DS shift */ ++#define FC_FROMDS 0x200 /* from DS */ ++#define FC_FROMDS_SHIFT 9 /* from DS shift */ ++#define FC_MOREFRAG 0x400 /* more frag. */ ++#define FC_MOREFRAG_SHIFT 10 /* more frag. shift */ ++#define FC_RETRY 0x800 /* retry */ ++#define FC_RETRY_SHIFT 11 /* retry shift */ ++#define FC_PM 0x1000 /* PM */ ++#define FC_PM_SHIFT 12 /* PM shift */ ++#define FC_MOREDATA 0x2000 /* more data */ ++#define FC_MOREDATA_SHIFT 13 /* more data shift */ ++#define FC_WEP 0x4000 /* WEP */ ++#define FC_WEP_SHIFT 14 /* WEP shift */ ++#define FC_ORDER 0x8000 /* order */ ++#define FC_ORDER_SHIFT 15 /* order shift */ ++ ++/* sequence control macros */ ++#define SEQNUM_SHIFT 4 /* seq. number shift */ ++#define SEQNUM_MAX 0x1000 /* max seqnum + 1 */ ++#define FRAGNUM_MASK 0xF /* frag. number mask */ ++ ++/* Frame Control type/subtype defs */ ++ ++/* FC Types */ ++#define FC_TYPE_MNG 0 /* management type */ ++#define FC_TYPE_CTL 1 /* control type */ ++#define FC_TYPE_DATA 2 /* data type */ ++ ++/* Management Subtypes */ ++#define FC_SUBTYPE_ASSOC_REQ 0 /* assoc. request */ ++#define FC_SUBTYPE_ASSOC_RESP 1 /* assoc. response */ ++#define FC_SUBTYPE_REASSOC_REQ 2 /* reassoc. request */ ++#define FC_SUBTYPE_REASSOC_RESP 3 /* reassoc. response */ ++#define FC_SUBTYPE_PROBE_REQ 4 /* probe request */ ++#define FC_SUBTYPE_PROBE_RESP 5 /* probe response */ ++#define FC_SUBTYPE_BEACON 8 /* beacon */ ++#define FC_SUBTYPE_ATIM 9 /* ATIM */ ++#define FC_SUBTYPE_DISASSOC 10 /* disassoc. */ ++#define FC_SUBTYPE_AUTH 11 /* authentication */ ++#define FC_SUBTYPE_DEAUTH 12 /* de-authentication */ ++#define FC_SUBTYPE_ACTION 13 /* action */ ++#define FC_SUBTYPE_ACTION_NOACK 14 /* action no-ack */ ++ ++/* Control Subtypes */ ++#define FC_SUBTYPE_CTL_WRAPPER 7 /* Control Wrapper */ ++#define FC_SUBTYPE_BLOCKACK_REQ 8 /* Block Ack Req */ ++#define FC_SUBTYPE_BLOCKACK 9 /* Block Ack */ ++#define FC_SUBTYPE_PS_POLL 10 /* PS poll */ ++#define FC_SUBTYPE_RTS 11 /* RTS */ ++#define FC_SUBTYPE_CTS 12 /* CTS */ ++#define FC_SUBTYPE_ACK 13 /* ACK */ ++#define FC_SUBTYPE_CF_END 14 /* CF-END */ ++#define FC_SUBTYPE_CF_END_ACK 15 /* CF-END ACK */ ++ ++/* Data Subtypes */ ++#define FC_SUBTYPE_DATA 0 /* Data */ ++#define FC_SUBTYPE_DATA_CF_ACK 1 /* Data + CF-ACK */ ++#define FC_SUBTYPE_DATA_CF_POLL 2 /* Data + CF-Poll */ ++#define FC_SUBTYPE_DATA_CF_ACK_POLL 3 /* Data + CF-Ack + CF-Poll */ ++#define FC_SUBTYPE_NULL 4 /* Null */ ++#define FC_SUBTYPE_CF_ACK 5 /* CF-Ack */ ++#define FC_SUBTYPE_CF_POLL 6 /* CF-Poll */ ++#define FC_SUBTYPE_CF_ACK_POLL 7 /* CF-Ack + CF-Poll */ ++#define FC_SUBTYPE_QOS_DATA 8 /* QoS Data */ ++#define FC_SUBTYPE_QOS_DATA_CF_ACK 9 /* QoS Data + CF-Ack */ ++#define FC_SUBTYPE_QOS_DATA_CF_POLL 10 /* QoS Data + CF-Poll */ ++#define FC_SUBTYPE_QOS_DATA_CF_ACK_POLL 11 /* QoS Data + CF-Ack + CF-Poll */ ++#define FC_SUBTYPE_QOS_NULL 12 /* QoS Null */ ++#define FC_SUBTYPE_QOS_CF_POLL 14 /* QoS CF-Poll */ ++#define FC_SUBTYPE_QOS_CF_ACK_POLL 15 /* QoS CF-Ack + CF-Poll */ ++ ++/* Data Subtype Groups */ ++#define FC_SUBTYPE_ANY_QOS(s) (((s) & 8) != 0) ++#define FC_SUBTYPE_ANY_NULL(s) (((s) & 4) != 0) ++#define FC_SUBTYPE_ANY_CF_POLL(s) (((s) & 2) != 0) ++#define FC_SUBTYPE_ANY_CF_ACK(s) (((s) & 1) != 0) ++ ++/* Type/Subtype Combos */ ++#define FC_KIND_MASK (FC_TYPE_MASK | FC_SUBTYPE_MASK) /* FC kind mask */ ++ ++#define FC_KIND(t, s) (((t) << FC_TYPE_SHIFT) | ((s) << FC_SUBTYPE_SHIFT)) /* FC kind */ ++ ++#define FC_SUBTYPE(fc) (((fc) & FC_SUBTYPE_MASK) >> FC_SUBTYPE_SHIFT) /* Subtype from FC */ ++#define FC_TYPE(fc) (((fc) & FC_TYPE_MASK) >> FC_TYPE_SHIFT) /* Type from FC */ ++ ++#define FC_ASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_REQ) /* assoc. request */ ++#define FC_ASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_RESP) /* assoc. response */ ++#define FC_REASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_REQ) /* reassoc. request */ ++#define FC_REASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_RESP) /* reassoc. response */ ++#define FC_PROBE_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_REQ) /* probe request */ ++#define FC_PROBE_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_RESP) /* probe response */ ++#define FC_BEACON FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_BEACON) /* beacon */ ++#define FC_DISASSOC FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DISASSOC) /* disassoc */ ++#define FC_AUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_AUTH) /* authentication */ ++#define FC_DEAUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DEAUTH) /* deauthentication */ ++#define FC_ACTION FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ACTION) /* action */ ++#define FC_ACTION_NOACK FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ACTION_NOACK) /* action no-ack */ ++ ++#define FC_CTL_WRAPPER FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CTL_WRAPPER) /* Control Wrapper */ ++#define FC_BLOCKACK_REQ FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_BLOCKACK_REQ) /* Block Ack Req */ ++#define FC_BLOCKACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_BLOCKACK) /* Block Ack */ ++#define FC_PS_POLL FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_PS_POLL) /* PS poll */ ++#define FC_RTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_RTS) /* RTS */ ++#define FC_CTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CTS) /* CTS */ ++#define FC_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_ACK) /* ACK */ ++#define FC_CF_END FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END) /* CF-END */ ++#define FC_CF_END_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END_ACK) /* CF-END ACK */ ++ ++#define FC_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA) /* data */ ++#define FC_NULL_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_NULL) /* null data */ ++#define FC_DATA_CF_ACK FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA_CF_ACK) /* data CF ACK */ ++#define FC_QOS_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_DATA) /* QoS data */ ++#define FC_QOS_NULL FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_NULL) /* QoS null */ ++ ++/* QoS Control Field */ ++ ++/* 802.1D Priority */ ++#define QOS_PRIO_SHIFT 0 /* QoS priority shift */ ++#define QOS_PRIO_MASK 0x0007 /* QoS priority mask */ ++#define QOS_PRIO(qos) (((qos) & QOS_PRIO_MASK) >> QOS_PRIO_SHIFT) /* QoS priority */ ++ ++/* Traffic Identifier */ ++#define QOS_TID_SHIFT 0 /* QoS TID shift */ ++#define QOS_TID_MASK 0x000f /* QoS TID mask */ ++#define QOS_TID(qos) (((qos) & QOS_TID_MASK) >> QOS_TID_SHIFT) /* QoS TID */ ++ ++/* End of Service Period (U-APSD) */ ++#define QOS_EOSP_SHIFT 4 /* QoS End of Service Period shift */ ++#define QOS_EOSP_MASK 0x0010 /* QoS End of Service Period mask */ ++#define QOS_EOSP(qos) (((qos) & QOS_EOSP_MASK) >> QOS_EOSP_SHIFT) /* Qos EOSP */ ++ ++/* Ack Policy */ ++#define QOS_ACK_NORMAL_ACK 0 /* Normal Ack */ ++#define QOS_ACK_NO_ACK 1 /* No Ack (eg mcast) */ ++#define QOS_ACK_NO_EXP_ACK 2 /* No Explicit Ack */ ++#define QOS_ACK_BLOCK_ACK 3 /* Block Ack */ ++#define QOS_ACK_SHIFT 5 /* QoS ACK shift */ ++#define QOS_ACK_MASK 0x0060 /* QoS ACK mask */ ++#define QOS_ACK(qos) (((qos) & QOS_ACK_MASK) >> QOS_ACK_SHIFT) /* QoS ACK */ ++ ++/* A-MSDU flag */ ++#define QOS_AMSDU_SHIFT 7 /* AMSDU shift */ ++#define QOS_AMSDU_MASK 0x0080 /* AMSDU mask */ ++ ++/* Management Frames */ ++ ++/* Management Frame Constants */ ++ ++/* Fixed fields */ ++#define DOT11_MNG_AUTH_ALGO_LEN 2 /* d11 management auth. algo. length */ ++#define DOT11_MNG_AUTH_SEQ_LEN 2 /* d11 management auth. seq. length */ ++#define DOT11_MNG_BEACON_INT_LEN 2 /* d11 management beacon interval length */ ++#define DOT11_MNG_CAP_LEN 2 /* d11 management cap. length */ ++#define DOT11_MNG_AP_ADDR_LEN 6 /* d11 management AP address length */ ++#define DOT11_MNG_LISTEN_INT_LEN 2 /* d11 management listen interval length */ ++#define DOT11_MNG_REASON_LEN 2 /* d11 management reason length */ ++#define DOT11_MNG_AID_LEN 2 /* d11 management AID length */ ++#define DOT11_MNG_STATUS_LEN 2 /* d11 management status length */ ++#define DOT11_MNG_TIMESTAMP_LEN 8 /* d11 management timestamp length */ ++ ++/* DUR/ID field in assoc resp is 0xc000 | AID */ ++#define DOT11_AID_MASK 0x3fff /* d11 AID mask */ ++ ++/* Reason Codes */ ++#define DOT11_RC_RESERVED 0 /* d11 RC reserved */ ++#define DOT11_RC_UNSPECIFIED 1 /* Unspecified reason */ ++#define DOT11_RC_AUTH_INVAL 2 /* Previous authentication no longer valid */ ++#define DOT11_RC_DEAUTH_LEAVING 3 /* Deauthenticated because sending station ++ * is leaving (or has left) IBSS or ESS ++ */ ++#define DOT11_RC_INACTIVITY 4 /* Disassociated due to inactivity */ ++#define DOT11_RC_BUSY 5 /* Disassociated because AP is unable to handle ++ * all currently associated stations ++ */ ++#define DOT11_RC_INVAL_CLASS_2 6 /* Class 2 frame received from ++ * nonauthenticated station ++ */ ++#define DOT11_RC_INVAL_CLASS_3 7 /* Class 3 frame received from ++ * nonassociated station ++ */ ++#define DOT11_RC_DISASSOC_LEAVING 8 /* Disassociated because sending station is ++ * leaving (or has left) BSS ++ */ ++#define DOT11_RC_NOT_AUTH 9 /* Station requesting (re)association is not ++ * authenticated with responding station ++ */ ++#define DOT11_RC_BAD_PC 10 /* Unacceptable power capability element */ ++#define DOT11_RC_BAD_CHANNELS 11 /* Unacceptable supported channels element */ ++/* 12 is unused */ ++ ++/* 32-39 are QSTA specific reasons added in 11e */ ++#define DOT11_RC_UNSPECIFIED_QOS 32 /* unspecified QoS-related reason */ ++#define DOT11_RC_INSUFFCIENT_BW 33 /* QAP lacks sufficient bandwidth */ ++#define DOT11_RC_EXCESSIVE_FRAMES 34 /* excessive number of frames need ack */ ++#define DOT11_RC_TX_OUTSIDE_TXOP 35 /* transmitting outside the limits of txop */ ++#define DOT11_RC_LEAVING_QBSS 36 /* QSTA is leaving the QBSS (or restting) */ ++#define DOT11_RC_BAD_MECHANISM 37 /* does not want to use the mechanism */ ++#define DOT11_RC_SETUP_NEEDED 38 /* mechanism needs a setup */ ++#define DOT11_RC_TIMEOUT 39 /* timeout */ ++ ++#define DOT11_RC_MAX 23 /* Reason codes > 23 are reserved */ ++ ++#define DOT11_RC_TDLS_PEER_UNREACH 25 ++#define DOT11_RC_TDLS_DOWN_UNSPECIFIED 26 ++ ++/* Status Codes */ ++#define DOT11_SC_SUCCESS 0 /* Successful */ ++#define DOT11_SC_FAILURE 1 /* Unspecified failure */ ++#define DOT11_SC_TDLS_WAKEUP_SCH_ALT 2 /* TDLS wakeup schedule rejected but alternative */ ++ /* schedule provided */ ++#define DOT11_SC_TDLS_WAKEUP_SCH_REJ 3 /* TDLS wakeup schedule rejected */ ++#define DOT11_SC_TDLS_SEC_DISABLED 5 /* TDLS Security disabled */ ++#define DOT11_SC_LIFETIME_REJ 6 /* Unacceptable lifetime */ ++#define DOT11_SC_NOT_SAME_BSS 7 /* Not in same BSS */ ++#define DOT11_SC_CAP_MISMATCH 10 /* Cannot support all requested ++ * capabilities in the Capability ++ * Information field ++ */ ++#define DOT11_SC_REASSOC_FAIL 11 /* Reassociation denied due to inability ++ * to confirm that association exists ++ */ ++#define DOT11_SC_ASSOC_FAIL 12 /* Association denied due to reason ++ * outside the scope of this standard ++ */ ++#define DOT11_SC_AUTH_MISMATCH 13 /* Responding station does not support ++ * the specified authentication ++ * algorithm ++ */ ++#define DOT11_SC_AUTH_SEQ 14 /* Received an Authentication frame ++ * with authentication transaction ++ * sequence number out of expected ++ * sequence ++ */ ++#define DOT11_SC_AUTH_CHALLENGE_FAIL 15 /* Authentication rejected because of ++ * challenge failure ++ */ ++#define DOT11_SC_AUTH_TIMEOUT 16 /* Authentication rejected due to timeout ++ * waiting for next frame in sequence ++ */ ++#define DOT11_SC_ASSOC_BUSY_FAIL 17 /* Association denied because AP is ++ * unable to handle additional ++ * associated stations ++ */ ++#define DOT11_SC_ASSOC_RATE_MISMATCH 18 /* Association denied due to requesting ++ * station not supporting all of the ++ * data rates in the BSSBasicRateSet ++ * parameter ++ */ ++#define DOT11_SC_ASSOC_SHORT_REQUIRED 19 /* Association denied due to requesting ++ * station not supporting the Short ++ * Preamble option ++ */ ++#define DOT11_SC_ASSOC_PBCC_REQUIRED 20 /* Association denied due to requesting ++ * station not supporting the PBCC ++ * Modulation option ++ */ ++#define DOT11_SC_ASSOC_AGILITY_REQUIRED 21 /* Association denied due to requesting ++ * station not supporting the Channel ++ * Agility option ++ */ ++#define DOT11_SC_ASSOC_SPECTRUM_REQUIRED 22 /* Association denied because Spectrum ++ * Management capability is required. ++ */ ++#define DOT11_SC_ASSOC_BAD_POWER_CAP 23 /* Association denied because the info ++ * in the Power Cap element is ++ * unacceptable. ++ */ ++#define DOT11_SC_ASSOC_BAD_SUP_CHANNELS 24 /* Association denied because the info ++ * in the Supported Channel element is ++ * unacceptable ++ */ ++#define DOT11_SC_ASSOC_SHORTSLOT_REQUIRED 25 /* Association denied due to requesting ++ * station not supporting the Short Slot ++ * Time option ++ */ ++#define DOT11_SC_ASSOC_ERPBCC_REQUIRED 26 /* Association denied due to requesting ++ * station not supporting the ER-PBCC ++ * Modulation option ++ */ ++#define DOT11_SC_ASSOC_DSSOFDM_REQUIRED 27 /* Association denied due to requesting ++ * station not supporting the DSS-OFDM ++ * option ++ */ ++#define DOT11_SC_ASSOC_R0KH_UNREACHABLE 28 /* Association denied due to AP ++ * being unable to reach the R0 Key Holder ++ */ ++#define DOT11_SC_ASSOC_TRY_LATER 30 /* Association denied temporarily, try again later ++ */ ++#define DOT11_SC_ASSOC_MFP_VIOLATION 31 /* Association denied due to Robust Management ++ * frame policy violation ++ */ ++ ++#define DOT11_SC_DECLINED 37 /* request declined */ ++#define DOT11_SC_INVALID_PARAMS 38 /* One or more params have invalid values */ ++#define DOT11_SC_INVALID_PAIRWISE_CIPHER 42 /* invalid pairwise cipher */ ++#define DOT11_SC_INVALID_AKMP 43 /* Association denied due to invalid AKMP */ ++#define DOT11_SC_INVALID_RSNIE_CAP 45 /* invalid RSN IE capabilities */ ++#define DOT11_SC_DLS_NOT_ALLOWED 48 /* DLS is not allowed in the BSS by policy */ ++#define DOT11_SC_INVALID_PMKID 53 /* Association denied due to invalid PMKID */ ++#define DOT11_SC_INVALID_MDID 54 /* Association denied due to invalid MDID */ ++#define DOT11_SC_INVALID_FTIE 55 /* Association denied due to invalid FTIE */ ++ ++#define DOT11_SC_UNEXP_MSG 70 /* Unexpected message */ ++#define DOT11_SC_INVALID_SNONCE 71 /* Invalid SNonce */ ++#define DOT11_SC_INVALID_RSNIE 72 /* Invalid contents of RSNIE */ ++ ++/* Info Elts, length of INFORMATION portion of Info Elts */ ++#define DOT11_MNG_DS_PARAM_LEN 1 /* d11 management DS parameter length */ ++#define DOT11_MNG_IBSS_PARAM_LEN 2 /* d11 management IBSS parameter length */ ++ ++/* TIM Info element has 3 bytes fixed info in INFORMATION field, ++ * followed by 1 to 251 bytes of Partial Virtual Bitmap ++ */ ++#define DOT11_MNG_TIM_FIXED_LEN 3 /* d11 management TIM fixed length */ ++#define DOT11_MNG_TIM_DTIM_COUNT 0 /* d11 management DTIM count */ ++#define DOT11_MNG_TIM_DTIM_PERIOD 1 /* d11 management DTIM period */ ++#define DOT11_MNG_TIM_BITMAP_CTL 2 /* d11 management TIM BITMAP control */ ++#define DOT11_MNG_TIM_PVB 3 /* d11 management TIM PVB */ ++ ++/* TLV defines */ ++#define TLV_TAG_OFF 0 /* tag offset */ ++#define TLV_LEN_OFF 1 /* length offset */ ++#define TLV_HDR_LEN 2 /* header length */ ++#define TLV_BODY_OFF 2 /* body offset */ ++ ++/* Management Frame Information Element IDs */ ++#define DOT11_MNG_SSID_ID 0 /* d11 management SSID id */ ++#define DOT11_MNG_RATES_ID 1 /* d11 management rates id */ ++#define DOT11_MNG_FH_PARMS_ID 2 /* d11 management FH parameter id */ ++#define DOT11_MNG_DS_PARMS_ID 3 /* d11 management DS parameter id */ ++#define DOT11_MNG_CF_PARMS_ID 4 /* d11 management CF parameter id */ ++#define DOT11_MNG_TIM_ID 5 /* d11 management TIM id */ ++#define DOT11_MNG_IBSS_PARMS_ID 6 /* d11 management IBSS parameter id */ ++#define DOT11_MNG_COUNTRY_ID 7 /* d11 management country id */ ++#define DOT11_MNG_HOPPING_PARMS_ID 8 /* d11 management hopping parameter id */ ++#define DOT11_MNG_HOPPING_TABLE_ID 9 /* d11 management hopping table id */ ++#define DOT11_MNG_REQUEST_ID 10 /* d11 management request id */ ++#define DOT11_MNG_QBSS_LOAD_ID 11 /* d11 management QBSS Load id */ ++#define DOT11_MNG_EDCA_PARAM_ID 12 /* 11E EDCA Parameter id */ ++#define DOT11_MNG_CHALLENGE_ID 16 /* d11 management chanllenge id */ ++#define DOT11_MNG_PWR_CONSTRAINT_ID 32 /* 11H PowerConstraint */ ++#define DOT11_MNG_PWR_CAP_ID 33 /* 11H PowerCapability */ ++#define DOT11_MNG_TPC_REQUEST_ID 34 /* 11H TPC Request */ ++#define DOT11_MNG_TPC_REPORT_ID 35 /* 11H TPC Report */ ++#define DOT11_MNG_SUPP_CHANNELS_ID 36 /* 11H Supported Channels */ ++#define DOT11_MNG_CHANNEL_SWITCH_ID 37 /* 11H ChannelSwitch Announcement */ ++#define DOT11_MNG_MEASURE_REQUEST_ID 38 /* 11H MeasurementRequest */ ++#define DOT11_MNG_MEASURE_REPORT_ID 39 /* 11H MeasurementReport */ ++#define DOT11_MNG_QUIET_ID 40 /* 11H Quiet */ ++#define DOT11_MNG_IBSS_DFS_ID 41 /* 11H IBSS_DFS */ ++#define DOT11_MNG_ERP_ID 42 /* d11 management ERP id */ ++#define DOT11_MNG_TS_DELAY_ID 43 /* d11 management TS Delay id */ ++#define DOT11_MNG_HT_CAP 45 /* d11 mgmt HT cap id */ ++#define DOT11_MNG_QOS_CAP_ID 46 /* 11E QoS Capability id */ ++#define DOT11_MNG_NONERP_ID 47 /* d11 management NON-ERP id */ ++#define DOT11_MNG_RSN_ID 48 /* d11 management RSN id */ ++#define DOT11_MNG_EXT_RATES_ID 50 /* d11 management ext. rates id */ ++#define DOT11_MNG_AP_CHREP_ID 51 /* 11k AP Channel report id */ ++#define DOT11_MNG_NBR_REP_ID 52 /* 11k Neighbor report id */ ++#define DOT11_MNG_MDIE_ID 54 /* 11r Mobility domain id */ ++#define DOT11_MNG_FTIE_ID 55 /* 11r Fast Bss Transition id */ ++#define DOT11_MNG_FT_TI_ID 56 /* 11r Timeout Interval id */ ++#define DOT11_MNG_REGCLASS_ID 59 /* d11 management regulatory class id */ ++#define DOT11_MNG_EXT_CSA_ID 60 /* d11 Extended CSA */ ++#define DOT11_MNG_HT_ADD 61 /* d11 mgmt additional HT info */ ++#define DOT11_MNG_EXT_CHANNEL_OFFSET 62 /* d11 mgmt ext channel offset */ ++#define DOT11_MNG_WAPI_ID 68 /* d11 management WAPI id */ ++#define DOT11_MNG_TIME_ADVERTISE_ID 69 /* 11p time advertisement */ ++#define DOT11_MNG_RRM_CAP_ID 70 /* 11k radio measurement capability */ ++#define DOT11_MNG_HT_BSS_COEXINFO_ID 72 /* d11 mgmt OBSS Coexistence INFO */ ++#define DOT11_MNG_HT_BSS_CHANNEL_REPORT_ID 73 /* d11 mgmt OBSS Intolerant Channel list */ ++#define DOT11_MNG_HT_OBSS_ID 74 /* d11 mgmt OBSS HT info */ ++#define DOT11_MNG_CHANNEL_USAGE 97 /* 11v channel usage */ ++#define DOT11_MNG_TIME_ZONE_ID 98 /* 11v time zone */ ++#define DOT11_MNG_LINK_IDENTIFIER_ID 101 /* 11z TDLS Link Identifier IE */ ++#define DOT11_MNG_WAKEUP_SCHEDULE_ID 102 /* 11z TDLS Wakeup Schedule IE */ ++#define DOT11_MNG_CHANNEL_SWITCH_TIMING_ID 104 /* 11z TDLS Channel Switch Timing IE */ ++#define DOT11_MNG_PTI_CONTROL_ID 105 /* 11z TDLS PTI Control IE */ ++#define DOT11_MNG_PU_BUFFER_STATUS_ID 106 /* 11z TDLS PU Buffer Status IE */ ++#define DOT11_MNG_INTERWORKING_ID 107 /* 11u interworking */ ++#define DOT11_MNG_ADVERTISEMENT_ID 108 /* 11u advertisement protocol */ ++#define DOT11_MNG_EXP_BW_REQ_ID 109 /* 11u expedited bandwith request */ ++#define DOT11_MNG_QOS_MAP_ID 110 /* 11u QoS map set */ ++#define DOT11_MNG_ROAM_CONSORT_ID 111 /* 11u roaming consortium */ ++#define DOT11_MNG_EMERGCY_ALERT_ID 112 /* 11u emergency alert identifier */ ++#define DOT11_MNG_EXT_CAP_ID 127 /* d11 mgmt ext capability */ ++#define DOT11_MNG_VHT_CAP_ID 191 /* d11 mgmt VHT cap id */ ++#define DOT11_MNG_VHT_OPERATION_ID 192 /* d11 mgmt VHT op id */ ++ ++#define DOT11_MNG_WPA_ID 221 /* d11 management WPA id */ ++#define DOT11_MNG_PROPR_ID 221 /* d11 management proprietary id */ ++/* should start using this one instead of above two */ ++#define DOT11_MNG_VS_ID 221 /* d11 management Vendor Specific IE */ ++ ++/* Rate element Basic flag and rate mask */ ++#define DOT11_RATE_BASIC 0x80 /* flag for a Basic Rate */ ++#define DOT11_RATE_MASK 0x7F /* mask for numeric part of rate */ ++ ++/* ERP info element bit values */ ++#define DOT11_MNG_ERP_LEN 1 /* ERP is currently 1 byte long */ ++#define DOT11_MNG_NONERP_PRESENT 0x01 /* NonERP (802.11b) STAs are present ++ *in the BSS ++ */ ++#define DOT11_MNG_USE_PROTECTION 0x02 /* Use protection mechanisms for ++ *ERP-OFDM frames ++ */ ++#define DOT11_MNG_BARKER_PREAMBLE 0x04 /* Short Preambles: 0 == allowed, ++ * 1 == not allowed ++ */ ++/* TS Delay element offset & size */ ++#define DOT11_MGN_TS_DELAY_LEN 4 /* length of TS DELAY IE */ ++#define TS_DELAY_FIELD_SIZE 4 /* TS DELAY field size */ ++ ++/* Capability Information Field */ ++#define DOT11_CAP_ESS 0x0001 /* d11 cap. ESS */ ++#define DOT11_CAP_IBSS 0x0002 /* d11 cap. IBSS */ ++#define DOT11_CAP_POLLABLE 0x0004 /* d11 cap. pollable */ ++#define DOT11_CAP_POLL_RQ 0x0008 /* d11 cap. poll request */ ++#define DOT11_CAP_PRIVACY 0x0010 /* d11 cap. privacy */ ++#define DOT11_CAP_SHORT 0x0020 /* d11 cap. short */ ++#define DOT11_CAP_PBCC 0x0040 /* d11 cap. PBCC */ ++#define DOT11_CAP_AGILITY 0x0080 /* d11 cap. agility */ ++#define DOT11_CAP_SPECTRUM 0x0100 /* d11 cap. spectrum */ ++#define DOT11_CAP_SHORTSLOT 0x0400 /* d11 cap. shortslot */ ++#define DOT11_CAP_RRM 0x1000 /* d11 cap. 11k radio measurement */ ++#define DOT11_CAP_CCK_OFDM 0x2000 /* d11 cap. CCK/OFDM */ ++ ++/* Extended capabilities IE bitfields */ ++/* 20/40 BSS Coexistence Management support bit position */ ++#define DOT11_EXT_CAP_OBSS_COEX_MGMT 0 ++/* scheduled PSMP support bit position */ ++#define DOT11_EXT_CAP_SPSMP 6 ++/* BSS Transition Management support bit position */ ++#define DOT11_EXT_CAP_BSS_TRANSITION_MGMT 19 ++/* Interworking support bit position */ ++#define DOT11_EXT_CAP_IW 31 ++/* service Interval granularity bit position and mask */ ++#define DOT11_EXT_CAP_SI 41 ++#define DOT11_EXT_CAP_SI_MASK 0x0E ++ ++/* ++ * Action Frame Constants ++ */ ++#define DOT11_ACTION_HDR_LEN 2 /* action frame category + action field */ ++#define DOT11_ACTION_CAT_OFF 0 /* category offset */ ++#define DOT11_ACTION_ACT_OFF 1 /* action offset */ ++ ++/* Action Category field (sec 7.3.1.11) */ ++#define DOT11_ACTION_CAT_ERR_MASK 0x80 /* category error mask */ ++#define DOT11_ACTION_CAT_MASK 0x7F /* category mask */ ++#define DOT11_ACTION_CAT_SPECT_MNG 0 /* category spectrum management */ ++#define DOT11_ACTION_CAT_QOS 1 /* category QoS */ ++#define DOT11_ACTION_CAT_DLS 2 /* category DLS */ ++#define DOT11_ACTION_CAT_BLOCKACK 3 /* category block ack */ ++#define DOT11_ACTION_CAT_PUBLIC 4 /* category public */ ++#define DOT11_ACTION_CAT_RRM 5 /* category radio measurements */ ++#define DOT11_ACTION_CAT_FBT 6 /* category fast bss transition */ ++#define DOT11_ACTION_CAT_HT 7 /* category for HT */ ++#define DOT11_ACTION_CAT_SA_QUERY 8 /* security association query */ ++#define DOT11_ACTION_CAT_PDPA 9 /* protected dual of public action */ ++#define DOT11_ACTION_CAT_BSSMGMT 10 /* category for BSS transition management */ ++#define DOT11_ACTION_NOTIFICATION 17 ++#define DOT11_ACTION_CAT_VSP 126 /* protected vendor specific */ ++#define DOT11_ACTION_CAT_VS 127 /* category Vendor Specific */ ++ ++/* Spectrum Management Action IDs (sec 7.4.1) */ ++#define DOT11_SM_ACTION_M_REQ 0 /* d11 action measurement request */ ++#define DOT11_SM_ACTION_M_REP 1 /* d11 action measurement response */ ++#define DOT11_SM_ACTION_TPC_REQ 2 /* d11 action TPC request */ ++#define DOT11_SM_ACTION_TPC_REP 3 /* d11 action TPC response */ ++#define DOT11_SM_ACTION_CHANNEL_SWITCH 4 /* d11 action channel switch */ ++#define DOT11_SM_ACTION_EXT_CSA 5 /* d11 extened CSA for 11n */ ++ ++/* HT action ids */ ++#define DOT11_ACTION_ID_HT_CH_WIDTH 0 /* notify channel width action id */ ++#define DOT11_ACTION_ID_HT_MIMO_PS 1 /* mimo ps action id */ ++ ++/* Public action ids */ ++#define DOT11_PUB_ACTION_BSS_COEX_MNG 0 /* 20/40 Coexistence Management action id */ ++#define DOT11_PUB_ACTION_CHANNEL_SWITCH 4 /* d11 action channel switch */ ++ ++/* Block Ack action types */ ++#define DOT11_BA_ACTION_ADDBA_REQ 0 /* ADDBA Req action frame type */ ++#define DOT11_BA_ACTION_ADDBA_RESP 1 /* ADDBA Resp action frame type */ ++#define DOT11_BA_ACTION_DELBA 2 /* DELBA action frame type */ ++ ++/* ADDBA action parameters */ ++#define DOT11_ADDBA_PARAM_AMSDU_SUP 0x0001 /* AMSDU supported under BA */ ++#define DOT11_ADDBA_PARAM_POLICY_MASK 0x0002 /* policy mask(ack vs delayed) */ ++#define DOT11_ADDBA_PARAM_POLICY_SHIFT 1 /* policy shift */ ++#define DOT11_ADDBA_PARAM_TID_MASK 0x003c /* tid mask */ ++#define DOT11_ADDBA_PARAM_TID_SHIFT 2 /* tid shift */ ++#define DOT11_ADDBA_PARAM_BSIZE_MASK 0xffc0 /* buffer size mask */ ++#define DOT11_ADDBA_PARAM_BSIZE_SHIFT 6 /* buffer size shift */ ++ ++#define DOT11_ADDBA_POLICY_DELAYED 0 /* delayed BA policy */ ++#define DOT11_ADDBA_POLICY_IMMEDIATE 1 /* immediate BA policy */ ++ ++/* Fast Transition action types */ ++#define DOT11_FT_ACTION_FT_RESERVED 0 ++#define DOT11_FT_ACTION_FT_REQ 1 /* FBT request - for over-the-DS FBT */ ++#define DOT11_FT_ACTION_FT_RES 2 /* FBT response - for over-the-DS FBT */ ++#define DOT11_FT_ACTION_FT_CON 3 /* FBT confirm - for OTDS with RRP */ ++#define DOT11_FT_ACTION_FT_ACK 4 /* FBT ack */ ++ ++/* DLS action types */ ++#define DOT11_DLS_ACTION_REQ 0 /* DLS Request */ ++#define DOT11_DLS_ACTION_RESP 1 /* DLS Response */ ++#define DOT11_DLS_ACTION_TD 2 /* DLS Teardown */ ++ ++/* Wireless Network Management (WNM) action types */ ++#define DOT11_WNM_ACTION_EVENT_REQ 0 ++#define DOT11_WNM_ACTION_EVENT_REP 1 ++#define DOT11_WNM_ACTION_DIAG_REQ 2 ++#define DOT11_WNM_ACTION_DIAG_REP 3 ++#define DOT11_WNM_ACTION_LOC_CFG_REQ 4 ++#define DOT11_WNM_ACTION_LOC_RFG_RESP 5 ++#define DOT11_WNM_ACTION_BSS_TRANS_QURY 6 ++#define DOT11_WNM_ACTION_BSS_TRANS_REQ 7 ++#define DOT11_WNM_ACTION_BSS_TRANS_RESP 8 ++#define DOT11_WNM_ACTION_FMS_REQ 9 ++#define DOT11_WNM_ACTION_FMS_RESP 10 ++#define DOT11_WNM_ACTION_COL_INTRFRNCE_REQ 11 ++#define DOT11_WNM_ACTION_COL_INTRFRNCE_REP 12 ++#define DOT11_WNM_ACTION_TFS_REQ 13 ++#define DOT11_WNM_ACTION_TFS_RESP 14 ++#define DOT11_WNM_ACTION_TFS_NOTIFY 15 ++#define DOT11_WNM_ACTION_WNM_SLEEP_REQ 16 ++#define DOT11_WNM_ACTION_WNM_SLEEP_RESP 17 ++#define DOT11_WNM_ACTION_TIM_BCAST_REQ 18 ++#define DOT11_WNM_ACTION_TIM_BCAST_RESP 19 ++#define DOT11_WNM_ACTION_QOS_TRFC_CAP_UPD 20 ++#define DOT11_WNM_ACTION_CHAN_USAGE_REQ 21 ++#define DOT11_WNM_ACTION_CHAN_USAGE_RESP 22 ++#define DOT11_WNM_ACTION_DMS_REQ 23 ++#define DOT11_WNM_ACTION_DMS_RESP 24 ++#define DOT11_WNM_ACTION_TMNG_MEASUR_REQ 25 ++#define DOT11_WNM_ACTION_NOTFCTN_REQ 26 ++#define DOT11_WNM_ACTION_NOTFCTN_RES 27 ++ ++#define DOT11_MNG_COUNTRY_ID_LEN 3 ++ ++/* DLS Request frame header */ ++BWL_PRE_PACKED_STRUCT struct dot11_dls_req { ++ uint8 category; /* category of action frame (2) */ ++ uint8 action; /* DLS action: req (0) */ ++ struct ether_addr da; /* destination address */ ++ struct ether_addr sa; /* source address */ ++ uint16 cap; /* capability */ ++ uint16 timeout; /* timeout value */ ++ uint8 data[1]; /* IE:support rate, extend support rate, HT cap */ ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_dls_req dot11_dls_req_t; ++#define DOT11_DLS_REQ_LEN 18 /* Fixed length */ ++ ++/* DLS response frame header */ ++BWL_PRE_PACKED_STRUCT struct dot11_dls_resp { ++ uint8 category; /* category of action frame (2) */ ++ uint8 action; /* DLS action: req (0) */ ++ uint16 status; /* status code field */ ++ struct ether_addr da; /* destination address */ ++ struct ether_addr sa; /* source address */ ++ uint8 data[1]; /* optional: capability, rate ... */ ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_dls_resp dot11_dls_resp_t; ++#define DOT11_DLS_RESP_LEN 16 /* Fixed length */ ++ ++ ++/* BSS Management Transition Query frame header */ ++BWL_PRE_PACKED_STRUCT struct dot11_bss_trans_query { ++ uint8 category; /* category of action frame (10) */ ++ uint8 action; /* WNM action: trans_query (6) */ ++ uint8 token; /* dialog token */ ++ uint8 reason; /* transition query reason */ ++ uint8 data[1]; /* Elements */ ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_bss_trans_query dot11_bss_trans_query_t; ++#define DOT11_BSS_TRANS_QUERY_LEN 4 /* Fixed length */ ++ ++/* BSS Management Transition Request frame header */ ++BWL_PRE_PACKED_STRUCT struct dot11_bss_trans_req { ++ uint8 category; /* category of action frame (10) */ ++ uint8 action; /* WNM action: trans_req (7) */ ++ uint8 token; /* dialog token */ ++ uint8 reqmode; /* transition request mode */ ++ uint16 disassoc_tmr; /* disassociation timer */ ++ uint8 validity_intrvl; /* validity interval */ ++ uint8 data[1]; /* optional: BSS term duration, ... */ ++ /* ...session info URL, list */ ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_bss_trans_req dot11_bss_trans_req_t; ++#define DOT11_BSS_TRANS_REQ_LEN 7 /* Fixed length */ ++ ++#define DOT11_BSS_TERM_DUR_LEN 12 /* Fixed length if present */ ++ ++ ++/* BSS Mgmt Transition Request Mode Field - 802.11v */ ++#define DOT11_BSS_TRNS_REQMODE_PREF_LIST_INCL 0x01 ++#define DOT11_BSS_TRNS_REQMODE_ABRIDGED 0x02 ++#define DOT11_BSS_TRNS_REQMODE_DISASSOC_IMMINENT 0x04 ++#define DOT11_BSS_TRNS_REQMODE_BSS_TERM_INCL 0x08 ++#define DOT11_BSS_TRNS_REQMODE_ESS_DISASSOC_IMNT 0x10 ++ ++ ++/* BSS Management transition response frame header */ ++BWL_PRE_PACKED_STRUCT struct dot11_bss_trans_res { ++ uint8 category; /* category of action frame (10) */ ++ uint8 action; /* WNM action: trans_res (8) */ ++ uint8 token; /* dialog token */ ++ uint8 status; /* transition status */ ++ uint8 term_delay; /* validity interval */ ++ uint8 data[1]; /* optional: BSS term duration, ... */ ++ /* ...session info URL, list */ ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_bss_trans_res dot11_bss_trans_res_t; ++#define DOT11_BSS_TRANS_RES_LEN 5 /* Fixed length */ ++ ++/* BSS Mgmt Transition Response Status Field */ ++#define DOT11_BSS_TRNS_RES_STATUS_ACCEPT 0 ++#define DOT11_BSS_TRNS_RES_STATUS_REJECT 1 ++#define DOT11_BSS_TRNS_RES_STATUS_REJ_INSUFF_BCN 2 ++#define DOT11_BSS_TRNS_RES_STATUS_REJ_INSUFF_CAP 3 ++#define DOT11_BSS_TRNS_RES_STATUS_REJ_TERM_UNDESIRED 4 ++#define DOT11_BSS_TRNS_RES_STATUS_REJ_TERM_DELAY_REQ 5 ++#define DOT11_BSS_TRNS_RES_STATUS_REJ_BSS_LIST_PROVIDED 6 ++#define DOT11_BSS_TRNS_RES_STATUS_REJ_NO_SUITABLE_BSS 7 ++#define DOT11_BSS_TRNS_RES_STATUS_REJ_LEAVING_ESS 8 ++ ++ ++/* Neighbor Report BSSID Information Field */ ++#define DOT11_NBR_RPRT_BSSID_INFO_REACHABILTY 0x0003 ++#define DOT11_NBR_RPRT_BSSID_INFO_SEC 0x0004 ++#define DOT11_NBR_RPRT_BSSID_INFO_KEY_SCOPE 0x0008 ++#define DOT11_NBR_RPRT_BSSID_INFO_CAP 0x03f0 ++ ++#define DOT11_NBR_RPRT_BSSID_INFO_CAP_SPEC_MGMT 0x0010 ++#define DOT11_NBR_RPRT_BSSID_INFO_CAP_QOS 0x0020 ++#define DOT11_NBR_RPRT_BSSID_INFO_CAP_APSD 0x0040 ++#define DOT11_NBR_RPRT_BSSID_INFO_CAP_RDIO_MSMT 0x0080 ++#define DOT11_NBR_RPRT_BSSID_INFO_CAP_DEL_BA 0x0100 ++#define DOT11_NBR_RPRT_BSSID_INFO_CAP_IMM_BA 0x0200 ++ ++/* Neighbor Report Subelements */ ++#define DOT11_NBR_RPRT_SUBELEM_BSS_CANDDT_PREF_ID 3 ++ ++ ++BWL_PRE_PACKED_STRUCT struct dot11_addba_req { ++ uint8 category; /* category of action frame (3) */ ++ uint8 action; /* action: addba req */ ++ uint8 token; /* identifier */ ++ uint16 addba_param_set; /* parameter set */ ++ uint16 timeout; /* timeout in seconds */ ++ uint16 start_seqnum; /* starting sequence number */ ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_addba_req dot11_addba_req_t; ++#define DOT11_ADDBA_REQ_LEN 9 /* length of addba req frame */ ++ ++BWL_PRE_PACKED_STRUCT struct dot11_addba_resp { ++ uint8 category; /* category of action frame (3) */ ++ uint8 action; /* action: addba resp */ ++ uint8 token; /* identifier */ ++ uint16 status; /* status of add request */ ++ uint16 addba_param_set; /* negotiated parameter set */ ++ uint16 timeout; /* negotiated timeout in seconds */ ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_addba_resp dot11_addba_resp_t; ++#define DOT11_ADDBA_RESP_LEN 9 /* length of addba resp frame */ ++ ++/* DELBA action parameters */ ++#define DOT11_DELBA_PARAM_INIT_MASK 0x0800 /* initiator mask */ ++#define DOT11_DELBA_PARAM_INIT_SHIFT 11 /* initiator shift */ ++#define DOT11_DELBA_PARAM_TID_MASK 0xf000 /* tid mask */ ++#define DOT11_DELBA_PARAM_TID_SHIFT 12 /* tid shift */ ++ ++BWL_PRE_PACKED_STRUCT struct dot11_delba { ++ uint8 category; /* category of action frame (3) */ ++ uint8 action; /* action: addba req */ ++ uint16 delba_param_set; /* paarmeter set */ ++ uint16 reason; /* reason for dellba */ ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_delba dot11_delba_t; ++#define DOT11_DELBA_LEN 6 /* length of delba frame */ ++ ++/* SA Query action field value */ ++#define SA_QUERY_REQUEST 0 ++#define SA_QUERY_RESPONSE 1 ++ ++/* ************* 802.11r related definitions. ************* */ ++ ++/* Over-the-DS Fast Transition Request frame header */ ++BWL_PRE_PACKED_STRUCT struct dot11_ft_req { ++ uint8 category; /* category of action frame (6) */ ++ uint8 action; /* action: ft req */ ++ uint8 sta_addr[ETHER_ADDR_LEN]; ++ uint8 tgt_ap_addr[ETHER_ADDR_LEN]; ++ uint8 data[1]; /* Elements */ ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_ft_req dot11_ft_req_t; ++#define DOT11_FT_REQ_FIXED_LEN 14 ++ ++/* Over-the-DS Fast Transition Response frame header */ ++BWL_PRE_PACKED_STRUCT struct dot11_ft_res { ++ uint8 category; /* category of action frame (6) */ ++ uint8 action; /* action: ft resp */ ++ uint8 sta_addr[ETHER_ADDR_LEN]; ++ uint8 tgt_ap_addr[ETHER_ADDR_LEN]; ++ uint16 status; /* status code */ ++ uint8 data[1]; /* Elements */ ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_ft_res dot11_ft_res_t; ++#define DOT11_FT_RES_FIXED_LEN 16 ++ ++ ++/* ************* 802.11k related definitions. ************* */ ++ ++/* Radio measurements enabled capability ie */ ++ ++#define DOT11_RRM_CAP_LEN 5 /* length of rrm cap bitmap */ ++BWL_PRE_PACKED_STRUCT struct dot11_rrm_cap_ie { ++ uint8 cap[DOT11_RRM_CAP_LEN]; ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_rrm_cap_ie dot11_rrm_cap_ie_t; ++ ++/* Bitmap definitions for cap ie */ ++#define DOT11_RRM_CAP_LINK 0 ++#define DOT11_RRM_CAP_NEIGHBOR_REPORT 1 ++#define DOT11_RRM_CAP_PARALLEL 2 ++#define DOT11_RRM_CAP_REPEATED 3 ++#define DOT11_RRM_CAP_BCN_PASSIVE 4 ++#define DOT11_RRM_CAP_BCN_ACTIVE 5 ++#define DOT11_RRM_CAP_BCN_TABLE 6 ++#define DOT11_RRM_CAP_BCN_REP_COND 7 ++#define DOT11_RRM_CAP_AP_CHANREP 16 ++ ++ ++/* Operating Class (formerly "Regulatory Class") definitions */ ++#define DOT11_OP_CLASS_NONE 255 ++ ++ ++/* Radio Measurements action ids */ ++#define DOT11_RM_ACTION_RM_REQ 0 /* Radio measurement request */ ++#define DOT11_RM_ACTION_RM_REP 1 /* Radio measurement report */ ++#define DOT11_RM_ACTION_LM_REQ 2 /* Link measurement request */ ++#define DOT11_RM_ACTION_LM_REP 3 /* Link measurement report */ ++#define DOT11_RM_ACTION_NR_REQ 4 /* Neighbor report request */ ++#define DOT11_RM_ACTION_NR_REP 5 /* Neighbor report response */ ++ ++/* Generic radio measurement action frame header */ ++BWL_PRE_PACKED_STRUCT struct dot11_rm_action { ++ uint8 category; /* category of action frame (5) */ ++ uint8 action; /* radio measurement action */ ++ uint8 token; /* dialog token */ ++ uint8 data[1]; ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_rm_action dot11_rm_action_t; ++#define DOT11_RM_ACTION_LEN 3 ++ ++BWL_PRE_PACKED_STRUCT struct dot11_rmreq { ++ uint8 category; /* category of action frame (5) */ ++ uint8 action; /* radio measurement action */ ++ uint8 token; /* dialog token */ ++ uint16 reps; /* no. of repetitions */ ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_rmreq dot11_rmreq_t; ++#define DOT11_RMREQ_LEN 5 ++ ++BWL_PRE_PACKED_STRUCT struct dot11_rm_ie { ++ uint8 id; ++ uint8 len; ++ uint8 token; ++ uint8 mode; ++ uint8 type; ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_rm_ie dot11_rm_ie_t; ++#define DOT11_RM_IE_LEN 5 ++ ++/* Definitions for "mode" bits in rm req */ ++#define DOT11_RMREQ_MODE_PARALLEL 1 ++#define DOT11_RMREQ_MODE_ENABLE 2 ++#define DOT11_RMREQ_MODE_REQUEST 4 ++#define DOT11_RMREQ_MODE_REPORT 8 ++#define DOT11_RMREQ_MODE_DURMAND 0x10 /* Duration Mandatory */ ++ ++/* Definitions for "mode" bits in rm rep */ ++#define DOT11_RMREP_MODE_LATE 1 ++#define DOT11_RMREP_MODE_INCAPABLE 2 ++#define DOT11_RMREP_MODE_REFUSED 4 ++ ++BWL_PRE_PACKED_STRUCT struct dot11_rmreq_bcn { ++ uint8 id; ++ uint8 len; ++ uint8 token; ++ uint8 mode; ++ uint8 type; ++ uint8 reg; ++ uint8 channel; ++ uint16 interval; ++ uint16 duration; ++ uint8 bcn_mode; ++ struct ether_addr bssid; ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_rmreq_bcn dot11_rmreq_bcn_t; ++#define DOT11_RMREQ_BCN_LEN 18 ++ ++BWL_PRE_PACKED_STRUCT struct dot11_rmrep_bcn { ++ uint8 reg; ++ uint8 channel; ++ uint32 starttime[2]; ++ uint16 duration; ++ uint8 frame_info; ++ uint8 rcpi; ++ uint8 rsni; ++ struct ether_addr bssid; ++ uint8 antenna_id; ++ uint32 parent_tsf; ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_rmrep_bcn dot11_rmrep_bcn_t; ++#define DOT11_RMREP_BCN_LEN 26 ++ ++/* Beacon request measurement mode */ ++#define DOT11_RMREQ_BCN_PASSIVE 0 ++#define DOT11_RMREQ_BCN_ACTIVE 1 ++#define DOT11_RMREQ_BCN_TABLE 2 ++ ++/* Sub-element IDs for Beacon Request */ ++#define DOT11_RMREQ_BCN_SSID_ID 0 ++#define DOT11_RMREQ_BCN_REPINFO_ID 1 ++#define DOT11_RMREQ_BCN_REPDET_ID 2 ++#define DOT11_RMREQ_BCN_REQUEST_ID 10 ++#define DOT11_RMREQ_BCN_APCHREP_ID 51 ++ ++/* Reporting Detail element definition */ ++#define DOT11_RMREQ_BCN_REPDET_FIXED 0 /* Fixed length fields only */ ++#define DOT11_RMREQ_BCN_REPDET_REQUEST 1 /* + requested information elems */ ++#define DOT11_RMREQ_BCN_REPDET_ALL 2 /* All fields */ ++ ++/* Sub-element IDs for Beacon Report */ ++#define DOT11_RMREP_BCN_FRM_BODY 1 ++ ++/* Neighbor measurement report */ ++BWL_PRE_PACKED_STRUCT struct dot11_rmrep_nbr { ++ struct ether_addr bssid; ++ uint32 bssid_info; ++ uint8 reg; ++ uint8 channel; ++ uint8 phytype; ++ uchar sub_elements[1]; /* Variable size data */ ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_rmrep_nbr dot11_rmrep_nbr_t; ++#define DOT11_RMREP_NBR_LEN 13 ++ ++/* MLME Enumerations */ ++#define DOT11_BSSTYPE_INFRASTRUCTURE 0 /* d11 infrastructure */ ++#define DOT11_BSSTYPE_INDEPENDENT 1 /* d11 independent */ ++#define DOT11_BSSTYPE_ANY 2 /* d11 any BSS type */ ++#define DOT11_SCANTYPE_ACTIVE 0 /* d11 scan active */ ++#define DOT11_SCANTYPE_PASSIVE 1 /* d11 scan passive */ ++ ++/* Link Measurement */ ++BWL_PRE_PACKED_STRUCT struct dot11_lmreq { ++ uint8 category; /* category of action frame (5) */ ++ uint8 action; /* radio measurement action */ ++ uint8 token; /* dialog token */ ++ uint8 txpwr; /* Transmit Power Used */ ++ uint8 maxtxpwr; /* Max Transmit Power */ ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_lmreq dot11_lmreq_t; ++#define DOT11_LMREQ_LEN 5 ++ ++BWL_PRE_PACKED_STRUCT struct dot11_lmrep { ++ uint8 category; /* category of action frame (5) */ ++ uint8 action; /* radio measurement action */ ++ uint8 token; /* dialog token */ ++ dot11_tpc_rep_t tpc; /* TPC element */ ++ uint8 rxant; /* Receive Antenna ID */ ++ uint8 txant; /* Transmit Antenna ID */ ++ uint8 rcpi; /* RCPI */ ++ uint8 rsni; /* RSNI */ ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_lmrep dot11_lmrep_t; ++#define DOT11_LMREP_LEN 11 ++ ++/* 802.11 BRCM "Compromise" Pre N constants */ ++#define PREN_PREAMBLE 24 /* green field preamble time */ ++#define PREN_MM_EXT 12 /* extra mixed mode preamble time */ ++#define PREN_PREAMBLE_EXT 4 /* extra preamble (multiply by unique_streams-1) */ ++ ++/* 802.11N PHY constants */ ++#define RIFS_11N_TIME 2 /* NPHY RIFS time */ ++ ++/* 802.11 HT PLCP format 802.11n-2009, sec 20.3.9.4.3 ++ * HT-SIG is composed of two 24 bit parts, HT-SIG1 and HT-SIG2 ++ */ ++/* HT-SIG1 */ ++#define HT_SIG1_MCS_MASK 0x00007F ++#define HT_SIG1_CBW 0x000080 ++#define HT_SIG1_HT_LENGTH 0xFFFF00 ++ ++/* HT-SIG2 */ ++#define HT_SIG2_SMOOTHING 0x000001 ++#define HT_SIG2_NOT_SOUNDING 0x000002 ++#define HT_SIG2_RESERVED 0x000004 ++#define HT_SIG2_AGGREGATION 0x000008 ++#define HT_SIG2_STBC_MASK 0x000030 ++#define HT_SIG2_STBC_SHIFT 4 ++#define HT_SIG2_FEC_CODING 0x000040 ++#define HT_SIG2_SHORT_GI 0x000080 ++#define HT_SIG2_ESS_MASK 0x000300 ++#define HT_SIG2_ESS_SHIFT 8 ++#define HT_SIG2_CRC 0x03FC00 ++#define HT_SIG2_TAIL 0x1C0000 ++ ++/* 802.11 A PHY constants */ ++#define APHY_SLOT_TIME 9 /* APHY slot time */ ++#define APHY_SIFS_TIME 16 /* APHY SIFS time */ ++#define APHY_DIFS_TIME (APHY_SIFS_TIME + (2 * APHY_SLOT_TIME)) /* APHY DIFS time */ ++#define APHY_PREAMBLE_TIME 16 /* APHY preamble time */ ++#define APHY_SIGNAL_TIME 4 /* APHY signal time */ ++#define APHY_SYMBOL_TIME 4 /* APHY symbol time */ ++#define APHY_SERVICE_NBITS 16 /* APHY service nbits */ ++#define APHY_TAIL_NBITS 6 /* APHY tail nbits */ ++#define APHY_CWMIN 15 /* APHY cwmin */ ++ ++/* 802.11 B PHY constants */ ++#define BPHY_SLOT_TIME 20 /* BPHY slot time */ ++#define BPHY_SIFS_TIME 10 /* BPHY SIFS time */ ++#define BPHY_DIFS_TIME 50 /* BPHY DIFS time */ ++#define BPHY_PLCP_TIME 192 /* BPHY PLCP time */ ++#define BPHY_PLCP_SHORT_TIME 96 /* BPHY PLCP short time */ ++#define BPHY_CWMIN 31 /* BPHY cwmin */ ++ ++/* 802.11 G constants */ ++#define DOT11_OFDM_SIGNAL_EXTENSION 6 /* d11 OFDM signal extension */ ++ ++#define PHY_CWMAX 1023 /* PHY cwmax */ ++ ++#define DOT11_MAXNUMFRAGS 16 /* max # fragments per MSDU */ ++ ++/* 802.11 AC (VHT) constants */ ++ ++typedef int vht_group_id_t; ++ ++/* for VHT-A1 */ ++/* SIG-A1 reserved bits */ ++#define VHT_SIGA1_CONST_MASK 0x800004 ++ ++#define VHT_SIGA1_20MHZ_VAL 0x000000 ++#define VHT_SIGA1_40MHZ_VAL 0x000001 ++#define VHT_SIGA1_80MHZ_VAL 0x000002 ++#define VHT_SIGA1_160MHZ_VAL 0x000003 ++ ++#define VHT_SIGA1_STBC 0x000008 ++ ++#define VHT_SIGA1_GID_MAX_GID 0x3f ++#define VHT_SIGA1_GID_SHIFT 4 ++#define VHT_SIGA1_GID_TO_AP 0x00 ++#define VHT_SIGA1_GID_NOT_TO_AP 0x3f ++ ++#define VHT_SIGA1_NSTS_SHIFT 10 ++#define VHT_SIGA1_NSTS_SHIFT_MASK_USER0 0x001C00 ++ ++#define VHT_SIGA1_PARTIAL_AID_SHIFT 13 ++ ++/* for VHT-A2 */ ++#define VHT_SIGA2_GI_NONE 0x000000 ++#define VHT_SIGA2_GI_SHORT 0x000001 ++#define VHT_SIGA2_GI_W_MOD10 0x000002 ++#define VHT_SIGA2_CODING_LDPC 0x000004 ++#define VHT_SIGA2_BEAMFORM_ENABLE 0x000100 ++#define VHT_SIGA2_MCS_SHIFT 4 ++ ++#define VHT_SIGA2_B9_RESERVED 0x000200 ++#define VHT_SIGA2_TAIL_MASK 0xfc0000 ++#define VHT_SIGA2_TAIL_VALUE 0x000000 ++ ++#define VHT_SIGA2_SVC_BITS 16 ++#define VHT_SIGA2_TAIL_BITS 6 ++ ++ ++/* dot11Counters Table - 802.11 spec., Annex D */ ++typedef struct d11cnt { ++ uint32 txfrag; /* dot11TransmittedFragmentCount */ ++ uint32 txmulti; /* dot11MulticastTransmittedFrameCount */ ++ uint32 txfail; /* dot11FailedCount */ ++ uint32 txretry; /* dot11RetryCount */ ++ uint32 txretrie; /* dot11MultipleRetryCount */ ++ uint32 rxdup; /* dot11FrameduplicateCount */ ++ uint32 txrts; /* dot11RTSSuccessCount */ ++ uint32 txnocts; /* dot11RTSFailureCount */ ++ uint32 txnoack; /* dot11ACKFailureCount */ ++ uint32 rxfrag; /* dot11ReceivedFragmentCount */ ++ uint32 rxmulti; /* dot11MulticastReceivedFrameCount */ ++ uint32 rxcrc; /* dot11FCSErrorCount */ ++ uint32 txfrmsnt; /* dot11TransmittedFrameCount */ ++ uint32 rxundec; /* dot11WEPUndecryptableCount */ ++} d11cnt_t; ++ ++/* OUI for BRCM proprietary IE */ ++#define BRCM_PROP_OUI "\x00\x90\x4C" /* Broadcom proprietary OUI */ ++ ++#ifndef LINUX_POSTMOGRIFY_REMOVAL ++/* The following BRCM_PROP_OUI types are currently in use (defined in ++ * relevant subsections). Each of them will be in a separate proprietary(221) IE ++ * #define SES_VNDR_IE_TYPE 1 (defined in src/ses/shared/ses.h) ++ * #define DPT_IE_TYPE 2 ++ * #define HT_CAP_IE_TYPE 51 ++ * #define HT_ADD_IE_TYPE 52 ++ * #define BRCM_EXTCH_IE_TYPE 53 ++ */ ++ ++/* Following is the generic structure for brcm_prop_ie (uses BRCM_PROP_OUI). ++ * DPT uses this format with type set to DPT_IE_TYPE ++ */ ++BWL_PRE_PACKED_STRUCT struct brcm_prop_ie_s { ++ uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */ ++ uint8 len; /* IE length */ ++ uint8 oui[3]; /* Proprietary OUI, BRCM_PROP_OUI */ ++ uint8 type; /* type of this IE */ ++ uint16 cap; /* DPT capabilities */ ++} BWL_POST_PACKED_STRUCT; ++typedef struct brcm_prop_ie_s brcm_prop_ie_t; ++ ++#define BRCM_PROP_IE_LEN 6 /* len of fixed part of brcm_prop ie */ ++ ++#define DPT_IE_TYPE 2 ++#define WET_TUNNEL_IE_TYPE 3 ++#endif /* LINUX_POSTMOGRIFY_REMOVAL */ ++ ++/* BRCM OUI: Used in the proprietary(221) IE in all broadcom devices */ ++#define BRCM_OUI "\x00\x10\x18" /* Broadcom OUI */ ++ ++/* BRCM info element */ ++BWL_PRE_PACKED_STRUCT struct brcm_ie { ++ uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */ ++ uint8 len; /* IE length */ ++ uint8 oui[3]; /* Proprietary OUI, BRCM_OUI */ ++ uint8 ver; /* type/ver of this IE */ ++ uint8 assoc; /* # of assoc STAs */ ++ uint8 flags; /* misc flags */ ++ uint8 flags1; /* misc flags */ ++ uint16 amsdu_mtu_pref; /* preferred A-MSDU MTU */ ++} BWL_POST_PACKED_STRUCT; ++typedef struct brcm_ie brcm_ie_t; ++#define BRCM_IE_LEN 11 /* BRCM IE length */ ++#define BRCM_IE_VER 2 /* BRCM IE version */ ++#define BRCM_IE_LEGACY_AES_VER 1 /* BRCM IE legacy AES version */ ++ ++/* brcm_ie flags */ ++#define BRF_LZWDS 0x4 /* lazy wds enabled */ ++#define BRF_BLOCKACK 0x8 /* BlockACK capable */ ++ ++/* brcm_ie flags1 */ ++#define BRF1_AMSDU 0x1 /* A-MSDU capable */ ++#define BRF1_WMEPS 0x4 /* AP is capable of handling WME + PS w/o APSD */ ++#define BRF1_PSOFIX 0x8 /* AP has fixed PS mode out-of-order packets */ ++#define BRF1_RX_LARGE_AGG 0x10 /* device can rx large aggregates */ ++#define BRF1_RFAWARE_DCS 0x20 /* RFAWARE dynamic channel selection (DCS) */ ++#define BRF1_SOFTAP 0x40 /* Configure as Broadcom SOFTAP */ ++ ++/* Vendor IE structure */ ++BWL_PRE_PACKED_STRUCT struct vndr_ie { ++ uchar id; ++ uchar len; ++ uchar oui [3]; ++ uchar data [1]; /* Variable size data */ ++} BWL_POST_PACKED_STRUCT; ++typedef struct vndr_ie vndr_ie_t; ++ ++#define VNDR_IE_HDR_LEN 2 /* id + len field */ ++#define VNDR_IE_MIN_LEN 3 /* size of the oui field */ ++#define VNDR_IE_MAX_LEN 256 /* verdor IE max length */ ++ ++/* ************* HT definitions. ************* */ ++#define MCSSET_LEN 16 /* 16-bits per 8-bit set to give 128-bits bitmap of MCS Index */ ++#define MAX_MCS_NUM (128) /* max mcs number = 128 */ ++ ++BWL_PRE_PACKED_STRUCT struct ht_cap_ie { ++ uint16 cap; ++ uint8 params; ++ uint8 supp_mcs[MCSSET_LEN]; ++ uint16 ext_htcap; ++ uint32 txbf_cap; ++ uint8 as_cap; ++} BWL_POST_PACKED_STRUCT; ++typedef struct ht_cap_ie ht_cap_ie_t; ++ ++/* CAP IE: HT 1.0 spec. simply stole a 802.11 IE, we use our prop. IE until this is resolved */ ++/* the capability IE is primarily used to convey this nodes abilities */ ++BWL_PRE_PACKED_STRUCT struct ht_prop_cap_ie { ++ uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */ ++ uint8 len; /* IE length */ ++ uint8 oui[3]; /* Proprietary OUI, BRCM_PROP_OUI */ ++ uint8 type; /* type inidicates what follows */ ++ ht_cap_ie_t cap_ie; ++} BWL_POST_PACKED_STRUCT; ++typedef struct ht_prop_cap_ie ht_prop_cap_ie_t; ++ ++#define HT_PROP_IE_OVERHEAD 4 /* overhead bytes for prop oui ie */ ++#define HT_CAP_IE_LEN 26 /* HT capability len (based on .11n d2.0) */ ++#define HT_CAP_IE_TYPE 51 ++ ++#define HT_CAP_LDPC_CODING 0x0001 /* Support for rx of LDPC coded pkts */ ++#define HT_CAP_40MHZ 0x0002 /* FALSE:20Mhz, TRUE:20/40MHZ supported */ ++#define HT_CAP_MIMO_PS_MASK 0x000C /* Mimo PS mask */ ++#define HT_CAP_MIMO_PS_SHIFT 0x0002 /* Mimo PS shift */ ++#define HT_CAP_MIMO_PS_OFF 0x0003 /* Mimo PS, no restriction */ ++#define HT_CAP_MIMO_PS_RTS 0x0001 /* Mimo PS, send RTS/CTS around MIMO frames */ ++#define HT_CAP_MIMO_PS_ON 0x0000 /* Mimo PS, MIMO disallowed */ ++#define HT_CAP_GF 0x0010 /* Greenfield preamble support */ ++#define HT_CAP_SHORT_GI_20 0x0020 /* 20MHZ short guard interval support */ ++#define HT_CAP_SHORT_GI_40 0x0040 /* 40Mhz short guard interval support */ ++#define HT_CAP_TX_STBC 0x0080 /* Tx STBC support */ ++#define HT_CAP_RX_STBC_MASK 0x0300 /* Rx STBC mask */ ++#define HT_CAP_RX_STBC_SHIFT 8 /* Rx STBC shift */ ++#define HT_CAP_DELAYED_BA 0x0400 /* delayed BA support */ ++#define HT_CAP_MAX_AMSDU 0x0800 /* Max AMSDU size in bytes , 0=3839, 1=7935 */ ++ ++#define HT_CAP_DSSS_CCK 0x1000 /* DSSS/CCK supported by the BSS */ ++#define HT_CAP_PSMP 0x2000 /* Power Save Multi Poll support */ ++#define HT_CAP_40MHZ_INTOLERANT 0x4000 /* 40MHz Intolerant */ ++#define HT_CAP_LSIG_TXOP 0x8000 /* L-SIG TXOP protection support */ ++ ++#define HT_CAP_RX_STBC_NO 0x0 /* no rx STBC support */ ++#define HT_CAP_RX_STBC_ONE_STREAM 0x1 /* rx STBC support of 1 spatial stream */ ++#define HT_CAP_RX_STBC_TWO_STREAM 0x2 /* rx STBC support of 1-2 spatial streams */ ++#define HT_CAP_RX_STBC_THREE_STREAM 0x3 /* rx STBC support of 1-3 spatial streams */ ++ ++#define VHT_MAX_MPDU 11454 /* max mpdu size for now (bytes) */ ++#define VHT_MPDU_MSDU_DELTA 56 /* Difference in spec - vht mpdu, amsdu len */ ++/* Max AMSDU len - per spec */ ++#define VHT_MAX_AMSDU (VHT_MAX_MPDU - VHT_MPDU_MSDU_DELTA) ++ ++#define HT_MAX_AMSDU 7935 /* max amsdu size (bytes) per the HT spec */ ++#define HT_MIN_AMSDU 3835 /* min amsdu size (bytes) per the HT spec */ ++ ++#define HT_PARAMS_RX_FACTOR_MASK 0x03 /* ampdu rcv factor mask */ ++#define HT_PARAMS_DENSITY_MASK 0x1C /* ampdu density mask */ ++#define HT_PARAMS_DENSITY_SHIFT 2 /* ampdu density shift */ ++ ++/* HT/AMPDU specific define */ ++#define AMPDU_MAX_MPDU_DENSITY 7 /* max mpdu density; in 1/8 usec units */ ++#define AMPDU_RX_FACTOR_8K 0 /* max rcv ampdu len (8kb) */ ++#define AMPDU_RX_FACTOR_16K 1 /* max rcv ampdu len (16kb) */ ++#define AMPDU_RX_FACTOR_32K 2 /* max rcv ampdu len (32kb) */ ++#define AMPDU_RX_FACTOR_64K 3 /* max rcv ampdu len (64kb) */ ++#define AMPDU_RX_FACTOR_BASE 8*1024 /* ampdu factor base for rx len */ ++ ++#define AMPDU_DELIMITER_LEN 4 /* length of ampdu delimiter */ ++#define AMPDU_DELIMITER_LEN_MAX 63 /* max length of ampdu delimiter(enforced in HW) */ ++ ++#define HT_CAP_EXT_PCO 0x0001 ++#define HT_CAP_EXT_PCO_TTIME_MASK 0x0006 ++#define HT_CAP_EXT_PCO_TTIME_SHIFT 1 ++#define HT_CAP_EXT_MCS_FEEDBACK_MASK 0x0300 ++#define HT_CAP_EXT_MCS_FEEDBACK_SHIFT 8 ++#define HT_CAP_EXT_HTC 0x0400 ++#define HT_CAP_EXT_RD_RESP 0x0800 ++ ++BWL_PRE_PACKED_STRUCT struct ht_add_ie { ++ uint8 ctl_ch; /* control channel number */ ++ uint8 byte1; /* ext ch,rec. ch. width, RIFS support */ ++ uint16 opmode; /* operation mode */ ++ uint16 misc_bits; /* misc bits */ ++ uint8 basic_mcs[MCSSET_LEN]; /* required MCS set */ ++} BWL_POST_PACKED_STRUCT; ++typedef struct ht_add_ie ht_add_ie_t; ++ ++/* ADD IE: HT 1.0 spec. simply stole a 802.11 IE, we use our prop. IE until this is resolved */ ++/* the additional IE is primarily used to convey the current BSS configuration */ ++BWL_PRE_PACKED_STRUCT struct ht_prop_add_ie { ++ uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */ ++ uint8 len; /* IE length */ ++ uint8 oui[3]; /* Proprietary OUI, BRCM_PROP_OUI */ ++ uint8 type; /* indicates what follows */ ++ ht_add_ie_t add_ie; ++} BWL_POST_PACKED_STRUCT; ++typedef struct ht_prop_add_ie ht_prop_add_ie_t; ++ ++#define HT_ADD_IE_LEN 22 ++#define HT_ADD_IE_TYPE 52 ++ ++/* byte1 defn's */ ++#define HT_BW_ANY 0x04 /* set, STA can use 20 or 40MHz */ ++#define HT_RIFS_PERMITTED 0x08 /* RIFS allowed */ ++ ++/* opmode defn's */ ++#define HT_OPMODE_MASK 0x0003 /* protection mode mask */ ++#define HT_OPMODE_SHIFT 0 /* protection mode shift */ ++#define HT_OPMODE_PURE 0x0000 /* protection mode PURE */ ++#define HT_OPMODE_OPTIONAL 0x0001 /* protection mode optional */ ++#define HT_OPMODE_HT20IN40 0x0002 /* protection mode 20MHz HT in 40MHz BSS */ ++#define HT_OPMODE_MIXED 0x0003 /* protection mode Mixed Mode */ ++#define HT_OPMODE_NONGF 0x0004 /* protection mode non-GF */ ++#define DOT11N_TXBURST 0x0008 /* Tx burst limit */ ++#define DOT11N_OBSS_NONHT 0x0010 /* OBSS Non-HT STA present */ ++ ++/* misc_bites defn's */ ++#define HT_BASIC_STBC_MCS 0x007f /* basic STBC MCS */ ++#define HT_DUAL_STBC_PROT 0x0080 /* Dual STBC Protection */ ++#define HT_SECOND_BCN 0x0100 /* Secondary beacon support */ ++#define HT_LSIG_TXOP 0x0200 /* L-SIG TXOP Protection full support */ ++#define HT_PCO_ACTIVE 0x0400 /* PCO active */ ++#define HT_PCO_PHASE 0x0800 /* PCO phase */ ++#define HT_DUALCTS_PROTECTION 0x0080 /* DUAL CTS protection needed */ ++ ++/* Tx Burst Limits */ ++#define DOT11N_2G_TXBURST_LIMIT 6160 /* 2G band Tx burst limit per 802.11n Draft 1.10 (usec) */ ++#define DOT11N_5G_TXBURST_LIMIT 3080 /* 5G band Tx burst limit per 802.11n Draft 1.10 (usec) */ ++ ++/* Macros for opmode */ ++#define GET_HT_OPMODE(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ ++ >> HT_OPMODE_SHIFT) ++#define HT_MIXEDMODE_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ ++ == HT_OPMODE_MIXED) /* mixed mode present */ ++#define HT_HT20_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ ++ == HT_OPMODE_HT20IN40) /* 20MHz HT present */ ++#define HT_OPTIONAL_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ ++ == HT_OPMODE_OPTIONAL) /* Optional protection present */ ++#define HT_USE_PROTECTION(add_ie) (HT_HT20_PRESENT((add_ie)) || \ ++ HT_MIXEDMODE_PRESENT((add_ie))) /* use protection */ ++#define HT_NONGF_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_NONGF) \ ++ == HT_OPMODE_NONGF) /* non-GF present */ ++#define DOT11N_TXBURST_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & DOT11N_TXBURST) \ ++ == DOT11N_TXBURST) /* Tx Burst present */ ++#define DOT11N_OBSS_NONHT_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & DOT11N_OBSS_NONHT) \ ++ == DOT11N_OBSS_NONHT) /* OBSS Non-HT present */ ++ ++BWL_PRE_PACKED_STRUCT struct obss_params { ++ uint16 passive_dwell; ++ uint16 active_dwell; ++ uint16 bss_widthscan_interval; ++ uint16 passive_total; ++ uint16 active_total; ++ uint16 chanwidth_transition_dly; ++ uint16 activity_threshold; ++} BWL_POST_PACKED_STRUCT; ++typedef struct obss_params obss_params_t; ++ ++BWL_PRE_PACKED_STRUCT struct dot11_obss_ie { ++ uint8 id; ++ uint8 len; ++ obss_params_t obss_params; ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_obss_ie dot11_obss_ie_t; ++#define DOT11_OBSS_SCAN_IE_LEN sizeof(obss_params_t) /* HT OBSS len (based on 802.11n d3.0) */ ++ ++/* HT control field */ ++#define HT_CTRL_LA_TRQ 0x00000002 /* sounding request */ ++#define HT_CTRL_LA_MAI 0x0000003C /* MCS request or antenna selection indication */ ++#define HT_CTRL_LA_MAI_SHIFT 2 ++#define HT_CTRL_LA_MAI_MRQ 0x00000004 /* MCS request */ ++#define HT_CTRL_LA_MAI_MSI 0x00000038 /* MCS request sequence identifier */ ++#define HT_CTRL_LA_MFSI 0x000001C0 /* MFB sequence identifier */ ++#define HT_CTRL_LA_MFSI_SHIFT 6 ++#define HT_CTRL_LA_MFB_ASELC 0x0000FE00 /* MCS feedback, antenna selection command/data */ ++#define HT_CTRL_LA_MFB_ASELC_SH 9 ++#define HT_CTRL_LA_ASELC_CMD 0x00000C00 /* ASEL command */ ++#define HT_CTRL_LA_ASELC_DATA 0x0000F000 /* ASEL data */ ++#define HT_CTRL_CAL_POS 0x00030000 /* Calibration position */ ++#define HT_CTRL_CAL_SEQ 0x000C0000 /* Calibration sequence */ ++#define HT_CTRL_CSI_STEERING 0x00C00000 /* CSI/Steering */ ++#define HT_CTRL_CSI_STEER_SHIFT 22 ++#define HT_CTRL_CSI_STEER_NFB 0 /* no fedback required */ ++#define HT_CTRL_CSI_STEER_CSI 1 /* CSI, H matrix */ ++#define HT_CTRL_CSI_STEER_NCOM 2 /* non-compressed beamforming */ ++#define HT_CTRL_CSI_STEER_COM 3 /* compressed beamforming */ ++#define HT_CTRL_NDP_ANNOUNCE 0x01000000 /* NDP announcement */ ++#define HT_CTRL_AC_CONSTRAINT 0x40000000 /* AC Constraint */ ++#define HT_CTRL_RDG_MOREPPDU 0x80000000 /* RDG/More PPDU */ ++ ++#define HT_OPMODE_OPTIONAL 0x0001 /* protection mode optional */ ++#define HT_OPMODE_HT20IN40 0x0002 /* protection mode 20MHz HT in 40MHz BSS */ ++#define HT_OPMODE_MIXED 0x0003 /* protection mode Mixed Mode */ ++#define HT_OPMODE_NONGF 0x0004 /* protection mode non-GF */ ++#define DOT11N_TXBURST 0x0008 /* Tx burst limit */ ++#define DOT11N_OBSS_NONHT 0x0010 /* OBSS Non-HT STA present */ ++ ++/* ************* VHT definitions. ************* */ ++ ++BWL_PRE_PACKED_STRUCT struct vht_cap_ie { ++ uint32 vht_cap_info; ++ /* supported MCS set - 64 bit field */ ++ uint16 rx_mcs_map; ++ uint16 rx_max_rate; ++ uint16 tx_mcs_map; ++ uint16 tx_max_rate; ++} BWL_POST_PACKED_STRUCT; ++typedef struct vht_cap_ie vht_cap_ie_t; ++/* 4B cap_info + 8B supp_mcs */ ++#define VHT_CAP_IE_LEN 12 ++/* 32bit - cap info */ ++#define VHT_CAP_INFO_MAX_MPDU_LEN_MASK 0x00000003 ++#define VHT_CAP_INFO_SUPP_CHAN_WIDTH_MASK 0x0000000c ++#define VHT_CAP_INFO_LDPC 0x00000010 ++#define VHT_CAP_INFO_SGI_80MHZ 0x00000020 ++#define VHT_CAP_INFO_SGI_160MHZ 0x00000040 ++#define VHT_CAP_INFO_TX_STBC 0x00000080 ++#define VHT_CAP_INFO_RX_STBC 0x00000700 ++ ++#define VHT_CAP_INFO_RX_STBC_MASK 0x00000700 ++#define VHT_CAP_INFO_RX_STBC_SHIFT 8 ++#define VHT_CAP_INFO_SU_BEAMFMR 0x00000800 ++#define VHT_CAP_INFO_SU_BEAMFMEE 0x00001000 ++#define VHT_CAP_INFO_NUM_BMFMR_ANT_MASK 0x0000e000 ++#define VHT_CAP_INFO_NUM_BMFMR_ANT_SHIFT 13 ++ ++#define VHT_CAP_INFO_NUM_SOUNDING_DIM_MASK 0x00070000 ++#define VHT_CAP_INFO_NUM_SOUNDING_DIM_SHIFT 16 ++#define VHT_CAP_INFO_MU_BEAMFMR 0x00080000 ++#define VHT_CAP_INFO_MU_BEAMFMEE 0x00100000 ++#define VHT_CAP_INFO_TXOPPS 0x00200000 ++#define VHT_CAP_INFO_HTCVHT 0x00400000 ++#define VHT_CAP_INFO_AMPDU_MAXLEN_EXP_MASK 0x03800000 ++#define VHT_CAP_INFO_AMPDU_MAXLEN_EXP_SHIFT 23 ++ ++#define VHT_CAP_INFO_LINK_ADAPT_CAP_MASK 0x0c000000 ++#define VHT_CAP_INFO_LINK_ADAPT_CAP_SHIFT 26 ++ ++/* 64-bit Supp MCS. */ ++#define VHT_CAP_SUPP_MCS_RX_HIGHEST_RATE_MASK 0x1fff ++#define VHT_CAP_SUPP_MCS_RX_HIGHEST_RATE_SHIFT 0 ++ ++#define VHT_CAP_SUPP_MCS_TX_HIGHEST_RATE_MASK 0x1fff ++#define VHT_CAP_SUPP_MCS_TX_HIGHEST_RATE_SHIFT 0 ++ ++#define VHT_CAP_MCS_MAP_0_7 0 ++#define VHT_CAP_MCS_MAP_0_8 1 ++#define VHT_CAP_MCS_MAP_0_9 2 ++#define VHT_CAP_MCS_MAP_NONE 3 ++ ++#define VHT_CAP_MCS_MAP_NSS_MAX 8 ++ ++/* VHT Capabilities Supported Channel Width */ ++typedef enum vht_cap_chan_width { ++ VHT_CAP_CHAN_WIDTH_20_40 = 0x00, ++ VHT_CAP_CHAN_WIDTH_80 = 0x04, ++ VHT_CAP_CHAN_WIDTH_160 = 0x08 ++} vht_cap_chan_width_t; ++ ++/* VHT Capabilities Supported max MPDU LEN */ ++typedef enum vht_cap_max_mpdu_len { ++ VHT_CAP_MPDU_MAX_4K = 0x00, ++ VHT_CAP_MPDU_MAX_8K = 0x01, ++ VHT_CAP_MPDU_MAX_11K = 0x02 ++} vht_cap_max_mpdu_len_t; ++ ++/* VHT Operation Element */ ++BWL_PRE_PACKED_STRUCT struct vht_op_ie { ++ uint8 chan_width; ++ uint8 chan1; ++ uint8 chan2; ++ uint16 supp_mcs; /* same def as above in vht cap */ ++} BWL_POST_PACKED_STRUCT; ++typedef struct vht_op_ie vht_op_ie_t; ++/* 3B VHT Op info + 2B Basic MCS */ ++#define VHT_OP_IE_LEN 5 ++ ++typedef enum vht_op_chan_width { ++ VHT_OP_CHAN_WIDTH_20_40 = 0, ++ VHT_OP_CHAN_WIDTH_80 = 1, ++ VHT_OP_CHAN_WIDTH_160 = 2, ++ VHT_OP_CHAN_WIDTH_80_80 = 3 ++} vht_op_chan_width_t; ++ ++/* Def for rx & tx basic mcs maps - ea ss num has 2 bits of info */ ++#define VHT_MCS_MAP_GET_SS_IDX(nss) (((nss)-1)*2) ++#define VHT_MCS_MAP_GET_MCS_PER_SS(nss, mcsMap) \ ++ (((mcsMap) >> VHT_MCS_MAP_GET_SS_IDX(nss)) & 0x3) ++#define VHT_MCS_MAP_SET_MCS_PER_SS(nss, numMcs, mcsMap) \ ++ ((mcsMap) |= (((numMcs) & 0x3) << VHT_MCS_MAP_GET_SS_IDX(nss))) ++ ++/* ************* WPA definitions. ************* */ ++#define WPA_OUI "\x00\x50\xF2" /* WPA OUI */ ++#define WPA_OUI_LEN 3 /* WPA OUI length */ ++#define WPA_OUI_TYPE 1 ++#define WPA_VERSION 1 /* WPA version */ ++#define WPA2_OUI "\x00\x0F\xAC" /* WPA2 OUI */ ++#define WPA2_OUI_LEN 3 /* WPA2 OUI length */ ++#define WPA2_VERSION 1 /* WPA2 version */ ++#define WPA2_VERSION_LEN 2 /* WAP2 version length */ ++ ++/* ************* WPS definitions. ************* */ ++#define WPS_OUI "\x00\x50\xF2" /* WPS OUI */ ++#define WPS_OUI_LEN 3 /* WPS OUI length */ ++#define WPS_OUI_TYPE 4 ++ ++/* ************* WFA definitions. ************* */ ++#if defined(MACOSX) ++#define MAC_OUI "\x00\x17\xF2" /* MACOSX OUI */ ++#define MAC_OUI_TYPE_P2P 5 ++#endif /* MACOSX */ ++ ++#if defined(MACOSX) && !defined(WLP2P_NEW_WFA_OUI) ++#define WFA_OUI WPS_OUI /* WFA OUI */ ++#else ++#ifdef P2P_IE_OVRD ++#define WFA_OUI MAC_OUI ++#else ++#define WFA_OUI "\x50\x6F\x9A" /* WFA OUI */ ++#endif /* P2P_IE_OVRD */ ++#endif /* MACOSX && !WLP2P_NEW_WFA_OUI */ ++#define WFA_OUI_LEN 3 /* WFA OUI length */ ++#ifdef P2P_IE_OVRD ++#define WFA_OUI_TYPE_P2P MAC_OUI_TYPE_P2P ++#else ++#define WFA_OUI_TYPE_P2P 9 ++#endif ++ ++#define WFA_OUI_TYPE_TPC 8 ++ ++/* RSN authenticated key managment suite */ ++#define RSN_AKM_NONE 0 /* None (IBSS) */ ++#define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */ ++#define RSN_AKM_PSK 2 /* Pre-shared Key */ ++#define RSN_AKM_FBT_1X 3 /* Fast Bss transition using 802.1X */ ++#define RSN_AKM_FBT_PSK 4 /* Fast Bss transition using Pre-shared Key */ ++#define RSN_AKM_MFP_1X 5 /* SHA256 key derivation, using 802.1X */ ++#define RSN_AKM_MFP_PSK 6 /* SHA256 key derivation, using Pre-shared Key */ ++#define RSN_AKM_TPK 7 /* TPK(TDLS Peer Key) handshake */ ++ ++/* Key related defines */ ++#define DOT11_MAX_DEFAULT_KEYS 4 /* number of default keys */ ++#define DOT11_MAX_KEY_SIZE 32 /* max size of any key */ ++#define DOT11_MAX_IV_SIZE 16 /* max size of any IV */ ++#define DOT11_EXT_IV_FLAG (1<<5) /* flag to indicate IV is > 4 bytes */ ++#define DOT11_WPA_KEY_RSC_LEN 8 /* WPA RSC key len */ ++ ++#define WEP1_KEY_SIZE 5 /* max size of any WEP key */ ++#define WEP1_KEY_HEX_SIZE 10 /* size of WEP key in hex. */ ++#define WEP128_KEY_SIZE 13 /* max size of any WEP key */ ++#define WEP128_KEY_HEX_SIZE 26 /* size of WEP key in hex. */ ++#define TKIP_MIC_SIZE 8 /* size of TKIP MIC */ ++#define TKIP_EOM_SIZE 7 /* max size of TKIP EOM */ ++#define TKIP_EOM_FLAG 0x5a /* TKIP EOM flag byte */ ++#define TKIP_KEY_SIZE 32 /* size of any TKIP key */ ++#define TKIP_MIC_AUTH_TX 16 /* offset to Authenticator MIC TX key */ ++#define TKIP_MIC_AUTH_RX 24 /* offset to Authenticator MIC RX key */ ++#define TKIP_MIC_SUP_RX TKIP_MIC_AUTH_TX /* offset to Supplicant MIC RX key */ ++#define TKIP_MIC_SUP_TX TKIP_MIC_AUTH_RX /* offset to Supplicant MIC TX key */ ++#define AES_KEY_SIZE 16 /* size of AES key */ ++#define AES_MIC_SIZE 8 /* size of AES MIC */ ++#define BIP_KEY_SIZE 16 /* size of BIP key */ ++ ++/* WCN */ ++#define WCN_OUI "\x00\x50\xf2" /* WCN OUI */ ++#define WCN_TYPE 4 /* WCN type */ ++ ++ ++/* 802.11r protocol definitions */ ++ ++/* Mobility Domain IE */ ++BWL_PRE_PACKED_STRUCT struct dot11_mdid_ie { ++ uint8 id; ++ uint8 len; ++ uint16 mdid; /* Mobility Domain Id */ ++ uint8 cap; ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_mdid_ie dot11_mdid_ie_t; ++ ++#define FBT_MDID_CAP_OVERDS 0x01 /* Fast Bss transition over the DS support */ ++#define FBT_MDID_CAP_RRP 0x02 /* Resource request protocol support */ ++ ++/* Fast Bss Transition IE */ ++BWL_PRE_PACKED_STRUCT struct dot11_ft_ie { ++ uint8 id; ++ uint8 len; ++ uint16 mic_control; /* Mic Control */ ++ uint8 mic[16]; ++ uint8 anonce[32]; ++ uint8 snonce[32]; ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_ft_ie dot11_ft_ie_t; ++ ++#define TIE_TYPE_RESERVED 0 ++#define TIE_TYPE_REASSOC_DEADLINE 1 ++#define TIE_TYPE_KEY_LIEFTIME 2 ++#define TIE_TYPE_ASSOC_COMEBACK 3 ++BWL_PRE_PACKED_STRUCT struct dot11_timeout_ie { ++ uint8 id; ++ uint8 len; ++ uint8 type; /* timeout interval type */ ++ uint32 value; /* timeout interval value */ ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_timeout_ie dot11_timeout_ie_t; ++ ++/* GTK ie */ ++BWL_PRE_PACKED_STRUCT struct dot11_gtk_ie { ++ uint8 id; ++ uint8 len; ++ uint16 key_info; ++ uint8 key_len; ++ uint8 rsc[8]; ++ uint8 data[1]; ++} BWL_POST_PACKED_STRUCT; ++typedef struct dot11_gtk_ie dot11_gtk_ie_t; ++ ++#define BSSID_INVALID "\x00\x00\x00\x00\x00\x00" ++#define BSSID_BROADCAST "\xFF\xFF\xFF\xFF\xFF\xFF" ++ ++ ++/* ************* WMM Parameter definitions. ************* */ ++#define WMM_OUI "\x00\x50\xF2" /* WNN OUI */ ++#define WMM_OUI_LEN 3 /* WMM OUI length */ ++#define WMM_OUI_TYPE 2 /* WMM OUT type */ ++#define WMM_VERSION 1 ++#define WMM_VERSION_LEN 1 ++ ++/* WMM OUI subtype */ ++#define WMM_OUI_SUBTYPE_PARAMETER 1 ++#define WMM_PARAMETER_IE_LEN 24 ++ ++/* Link Identifier Element */ ++BWL_PRE_PACKED_STRUCT struct link_id_ie { ++ uint8 id; ++ uint8 len; ++ struct ether_addr bssid; ++ struct ether_addr tdls_init_mac; ++ struct ether_addr tdls_resp_mac; ++} BWL_POST_PACKED_STRUCT; ++typedef struct link_id_ie link_id_ie_t; ++#define TDLS_LINK_ID_IE_LEN 18 ++ ++/* Link Wakeup Schedule Element */ ++BWL_PRE_PACKED_STRUCT struct wakeup_sch_ie { ++ uint8 id; ++ uint8 len; ++ uint32 offset; /* in ms between TSF0 and start of 1st Awake Window */ ++ uint32 interval; /* in ms bwtween the start of 2 Awake Windows */ ++ uint32 awake_win_slots; /* in backof slots, duration of Awake Window */ ++ uint32 max_wake_win; /* in ms, max duration of Awake Window */ ++ uint16 idle_cnt; /* number of consecutive Awake Windows */ ++} BWL_POST_PACKED_STRUCT; ++typedef struct wakeup_sch_ie wakeup_sch_ie_t; ++#define TDLS_WAKEUP_SCH_IE_LEN 18 ++ ++/* Channel Switch Timing Element */ ++BWL_PRE_PACKED_STRUCT struct channel_switch_timing_ie { ++ uint8 id; ++ uint8 len; ++ uint16 switch_time; /* in ms, time to switch channels */ ++ uint16 switch_timeout; /* in ms */ ++} BWL_POST_PACKED_STRUCT; ++typedef struct channel_switch_timing_ie channel_switch_timing_ie_t; ++#define TDLS_CHANNEL_SWITCH_TIMING_IE_LEN 4 ++ ++/* PTI Control Element */ ++BWL_PRE_PACKED_STRUCT struct pti_control_ie { ++ uint8 id; ++ uint8 len; ++ uint8 tid; ++ uint16 seq_control; ++} BWL_POST_PACKED_STRUCT; ++typedef struct pti_control_ie pti_control_ie_t; ++#define TDLS_PTI_CONTROL_IE_LEN 3 ++ ++/* PU Buffer Status Element */ ++BWL_PRE_PACKED_STRUCT struct pu_buffer_status_ie { ++ uint8 id; ++ uint8 len; ++ uint8 status; ++} BWL_POST_PACKED_STRUCT; ++typedef struct pu_buffer_status_ie pu_buffer_status_ie_t; ++#define TDLS_PU_BUFFER_STATUS_IE_LEN 1 ++#define TDLS_PU_BUFFER_STATUS_AC_BK 1 ++#define TDLS_PU_BUFFER_STATUS_AC_BE 2 ++#define TDLS_PU_BUFFER_STATUS_AC_VI 4 ++#define TDLS_PU_BUFFER_STATUS_AC_VO 8 ++ ++/* This marks the end of a packed structure section. */ ++#include ++ ++#endif /* _802_11_H_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/proto/802.1d.h b/drivers/net/ethernet/broadcom/gmac/src/include/proto/802.1d.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/proto/802.1d.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/proto/802.1d.h 2017-11-09 17:53:43.977301000 +0800 +@@ -0,0 +1,44 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Fundamental types and constants relating to 802.1D ++ * ++ * $Id: 802.1d.h 241182 2011-02-17 21:50:03Z $ ++ */ ++ ++#ifndef _802_1_D_ ++#define _802_1_D_ ++ ++/* 802.1D priority defines */ ++#define PRIO_8021D_NONE 2 /* None = - */ ++#define PRIO_8021D_BK 1 /* BK - Background */ ++#define PRIO_8021D_BE 0 /* BE - Best-effort */ ++#define PRIO_8021D_EE 3 /* EE - Excellent-effort */ ++#define PRIO_8021D_CL 4 /* CL - Controlled Load */ ++#define PRIO_8021D_VI 5 /* Vi - Video */ ++#define PRIO_8021D_VO 6 /* Vo - Voice */ ++#define PRIO_8021D_NC 7 /* NC - Network Control */ ++#define MAXPRIO 7 /* 0-7 */ ++#define NUMPRIO (MAXPRIO + 1) ++ ++#define ALLPRIO -1 /* All prioirty */ ++ ++/* Converts prio to precedence since the numerical value of ++ * PRIO_8021D_BE and PRIO_8021D_NONE are swapped. ++ */ ++#define PRIO2PREC(prio) \ ++ (((prio) == PRIO_8021D_NONE || (prio) == PRIO_8021D_BE) ? ((prio^2)) : (prio)) ++ ++#endif /* _802_1_D__ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/proto/BOM b/drivers/net/ethernet/broadcom/gmac/src/include/proto/BOM +--- a/drivers/net/ethernet/broadcom/gmac/src/include/proto/BOM 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/proto/BOM 2017-11-09 17:53:43.978294000 +0800 +@@ -0,0 +1,4 @@ ++# Created by mkbom ++# $Id: BOM,v 9.0 1998-07-30 23:19:02 $ ++ ++File 1.46 vip.h +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/proto/Makefile b/drivers/net/ethernet/broadcom/gmac/src/include/proto/Makefile +--- a/drivers/net/ethernet/broadcom/gmac/src/include/proto/Makefile 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/proto/Makefile 2017-11-09 17:53:43.979288000 +0800 +@@ -0,0 +1,21 @@ ++# ++# include/proto/Makefile ++# ++# Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++# ++# Permission to use, copy, modify, and/or distribute this software for any ++# purpose with or without fee is hereby granted, provided that the above ++# copyright notice and this permission notice appear in all copies. ++# ++# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++# ++# $Id: Makefile 241182 2011-02-17 21:50:03Z $ ++# ++ ++# build etags +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/proto/bcmeth.h b/drivers/net/ethernet/broadcom/gmac/src/include/proto/bcmeth.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/proto/bcmeth.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/proto/bcmeth.h 2017-11-09 17:53:43.979307000 +0800 +@@ -0,0 +1,106 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Broadcom Ethernettype protocol definitions ++ * ++ * $Id: bcmeth.h 294352 2011-11-06 19:23:00Z $ ++ */ ++ ++/* ++ * Broadcom Ethernet protocol defines ++ */ ++ ++#ifndef _BCMETH_H_ ++#define _BCMETH_H_ ++ ++#ifndef _TYPEDEFS_H_ ++#include ++#endif ++ ++/* This marks the start of a packed structure section. */ ++#include ++ ++/* ETHER_TYPE_BRCM is defined in ethernet.h */ ++ ++/* ++ * Following the 2byte BRCM ether_type is a 16bit BRCM subtype field ++ * in one of two formats: (only subtypes 32768-65535 are in use now) ++ * ++ * subtypes 0-32767: ++ * 8 bit subtype (0-127) ++ * 8 bit length in bytes (0-255) ++ * ++ * subtypes 32768-65535: ++ * 16 bit big-endian subtype ++ * 16 bit big-endian length in bytes (0-65535) ++ * ++ * length is the number of additional bytes beyond the 4 or 6 byte header ++ * ++ * Reserved values: ++ * 0 reserved ++ * 5-15 reserved for iLine protocol assignments ++ * 17-126 reserved, assignable ++ * 127 reserved ++ * 32768 reserved ++ * 32769-65534 reserved, assignable ++ * 65535 reserved ++ */ ++ ++/* ++ * While adding the subtypes and their specific processing code make sure ++ * bcmeth_bcm_hdr_t is the first data structure in the user specific data structure definition ++ */ ++ ++#define BCMILCP_SUBTYPE_RATE 1 ++#define BCMILCP_SUBTYPE_LINK 2 ++#define BCMILCP_SUBTYPE_CSA 3 ++#define BCMILCP_SUBTYPE_LARQ 4 ++#define BCMILCP_SUBTYPE_VENDOR 5 ++#define BCMILCP_SUBTYPE_FLH 17 ++ ++#define BCMILCP_SUBTYPE_VENDOR_LONG 32769 ++#define BCMILCP_SUBTYPE_CERT 32770 ++#define BCMILCP_SUBTYPE_SES 32771 ++ ++ ++#define BCMILCP_BCM_SUBTYPE_RESERVED 0 ++#define BCMILCP_BCM_SUBTYPE_EVENT 1 ++#define BCMILCP_BCM_SUBTYPE_SES 2 ++/* ++ * The EAPOL type is not used anymore. Instead EAPOL messages are now embedded ++ * within BCMILCP_BCM_SUBTYPE_EVENT type messages ++ */ ++/* #define BCMILCP_BCM_SUBTYPE_EAPOL 3 */ ++#define BCMILCP_BCM_SUBTYPE_DPT 4 ++ ++#define BCMILCP_BCM_SUBTYPEHDR_MINLENGTH 8 ++#define BCMILCP_BCM_SUBTYPEHDR_VERSION 0 ++ ++/* These fields are stored in network order */ ++typedef BWL_PRE_PACKED_STRUCT struct bcmeth_hdr ++{ ++ uint16 subtype; /* Vendor specific..32769 */ ++ uint16 length; ++ uint8 version; /* Version is 0 */ ++ uint8 oui[3]; /* Broadcom OUI */ ++ /* user specific Data */ ++ uint16 usr_subtype; ++} BWL_POST_PACKED_STRUCT bcmeth_hdr_t; ++ ++ ++/* This marks the end of a packed structure section. */ ++#include ++ ++#endif /* _BCMETH_H_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/proto/bcmevent.h b/drivers/net/ethernet/broadcom/gmac/src/include/proto/bcmevent.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/proto/bcmevent.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/proto/bcmevent.h 2017-11-09 17:53:43.988295000 +0800 +@@ -0,0 +1,313 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Broadcom Event protocol definitions ++ * ++ * Dependencies: proto/bcmeth.h ++ * ++ * $Id: bcmevent.h 315348 2012-02-16 07:32:51Z $ ++ * ++ */ ++ ++/* ++ * Broadcom Ethernet Events protocol defines ++ * ++ */ ++ ++#ifndef _BCMEVENT_H_ ++#define _BCMEVENT_H_ ++ ++#ifndef _TYPEDEFS_H_ ++#include ++#endif ++ ++/* This marks the start of a packed structure section. */ ++#include ++ ++#define BCM_EVENT_MSG_VERSION 2 /* wl_event_msg_t struct version */ ++#define BCM_MSG_IFNAME_MAX 16 /* max length of interface name */ ++ ++/* flags */ ++#define WLC_EVENT_MSG_LINK 0x01 /* link is up */ ++#define WLC_EVENT_MSG_FLUSHTXQ 0x02 /* flush tx queue on MIC error */ ++#define WLC_EVENT_MSG_GROUP 0x04 /* group MIC error */ ++#define WLC_EVENT_MSG_UNKBSS 0x08 /* unknown source bsscfg */ ++#define WLC_EVENT_MSG_UNKIF 0x10 /* unknown source OS i/f */ ++ ++/* these fields are stored in network order */ ++ ++/* version 1 */ ++typedef BWL_PRE_PACKED_STRUCT struct ++{ ++ uint16 version; ++ uint16 flags; /* see flags below */ ++ uint32 event_type; /* Message (see below) */ ++ uint32 status; /* Status code (see below) */ ++ uint32 reason; /* Reason code (if applicable) */ ++ uint32 auth_type; /* WLC_E_AUTH */ ++ uint32 datalen; /* data buf */ ++ struct ether_addr addr; /* Station address (if applicable) */ ++ char ifname[BCM_MSG_IFNAME_MAX]; /* name of the packet incoming interface */ ++} BWL_POST_PACKED_STRUCT wl_event_msg_v1_t; ++ ++/* the current version */ ++typedef BWL_PRE_PACKED_STRUCT struct ++{ ++ uint16 version; ++ uint16 flags; /* see flags below */ ++ uint32 event_type; /* Message (see below) */ ++ uint32 status; /* Status code (see below) */ ++ uint32 reason; /* Reason code (if applicable) */ ++ uint32 auth_type; /* WLC_E_AUTH */ ++ uint32 datalen; /* data buf */ ++ struct ether_addr addr; /* Station address (if applicable) */ ++ char ifname[BCM_MSG_IFNAME_MAX]; /* name of the packet incoming interface */ ++ uint8 ifidx; /* destination OS i/f index */ ++ uint8 bsscfgidx; /* source bsscfg index */ ++} BWL_POST_PACKED_STRUCT wl_event_msg_t; ++ ++/* used by driver msgs */ ++typedef BWL_PRE_PACKED_STRUCT struct bcm_event { ++ struct ether_header eth; ++ bcmeth_hdr_t bcm_hdr; ++ wl_event_msg_t event; ++ /* data portion follows */ ++} BWL_POST_PACKED_STRUCT bcm_event_t; ++ ++#define BCM_MSG_LEN (sizeof(bcm_event_t) - sizeof(bcmeth_hdr_t) - sizeof(struct ether_header)) ++ ++/* Event messages */ ++#define WLC_E_SET_SSID 0 /* indicates status of set SSID */ ++#define WLC_E_JOIN 1 /* differentiates join IBSS from found (WLC_E_START) IBSS */ ++#define WLC_E_START 2 /* STA founded an IBSS or AP started a BSS */ ++#define WLC_E_AUTH 3 /* 802.11 AUTH request */ ++#define WLC_E_AUTH_IND 4 /* 802.11 AUTH indication */ ++#define WLC_E_DEAUTH 5 /* 802.11 DEAUTH request */ ++#define WLC_E_DEAUTH_IND 6 /* 802.11 DEAUTH indication */ ++#define WLC_E_ASSOC 7 /* 802.11 ASSOC request */ ++#define WLC_E_ASSOC_IND 8 /* 802.11 ASSOC indication */ ++#define WLC_E_REASSOC 9 /* 802.11 REASSOC request */ ++#define WLC_E_REASSOC_IND 10 /* 802.11 REASSOC indication */ ++#define WLC_E_DISASSOC 11 /* 802.11 DISASSOC request */ ++#define WLC_E_DISASSOC_IND 12 /* 802.11 DISASSOC indication */ ++#define WLC_E_QUIET_START 13 /* 802.11h Quiet period started */ ++#define WLC_E_QUIET_END 14 /* 802.11h Quiet period ended */ ++#define WLC_E_BEACON_RX 15 /* BEACONS received/lost indication */ ++#define WLC_E_LINK 16 /* generic link indication */ ++#define WLC_E_MIC_ERROR 17 /* TKIP MIC error occurred */ ++#define WLC_E_NDIS_LINK 18 /* NDIS style link indication */ ++#define WLC_E_ROAM 19 /* roam attempt occurred: indicate status & reason */ ++#define WLC_E_TXFAIL 20 /* change in dot11FailedCount (txfail) */ ++#define WLC_E_PMKID_CACHE 21 /* WPA2 pmkid cache indication */ ++#define WLC_E_RETROGRADE_TSF 22 /* current AP's TSF value went backward */ ++#define WLC_E_PRUNE 23 /* AP was pruned from join list for reason */ ++#define WLC_E_AUTOAUTH 24 /* report AutoAuth table entry match for join attempt */ ++#define WLC_E_EAPOL_MSG 25 /* Event encapsulating an EAPOL message */ ++#define WLC_E_SCAN_COMPLETE 26 /* Scan results are ready or scan was aborted */ ++#define WLC_E_ADDTS_IND 27 /* indicate to host addts fail/success */ ++#define WLC_E_DELTS_IND 28 /* indicate to host delts fail/success */ ++#define WLC_E_BCNSENT_IND 29 /* indicate to host of beacon transmit */ ++#define WLC_E_BCNRX_MSG 30 /* Send the received beacon up to the host */ ++#define WLC_E_BCNLOST_MSG 31 /* indicate to host loss of beacon */ ++#define WLC_E_ROAM_PREP 32 /* before attempting to roam */ ++#define WLC_E_PFN_NET_FOUND 33 /* PFN network found event */ ++#define WLC_E_PFN_NET_LOST 34 /* PFN network lost event */ ++#define WLC_E_RESET_COMPLETE 35 ++#define WLC_E_JOIN_START 36 ++#define WLC_E_ROAM_START 37 ++#define WLC_E_ASSOC_START 38 ++#define WLC_E_IBSS_ASSOC 39 ++#define WLC_E_RADIO 40 ++#define WLC_E_PSM_WATCHDOG 41 /* PSM microcode watchdog fired */ ++#define WLC_E_PROBREQ_MSG 44 /* probe request received */ ++#define WLC_E_SCAN_CONFIRM_IND 45 ++#define WLC_E_PSK_SUP 46 /* WPA Handshake fail */ ++#define WLC_E_COUNTRY_CODE_CHANGED 47 ++#define WLC_E_EXCEEDED_MEDIUM_TIME 48 /* WMMAC excedded medium time */ ++#define WLC_E_ICV_ERROR 49 /* WEP ICV error occurred */ ++#define WLC_E_UNICAST_DECODE_ERROR 50 /* Unsupported unicast encrypted frame */ ++#define WLC_E_MULTICAST_DECODE_ERROR 51 /* Unsupported multicast encrypted frame */ ++#define WLC_E_TRACE 52 ++#define WLC_E_IF 54 /* I/F change (for dongle host notification) */ ++#define WLC_E_P2P_DISC_LISTEN_COMPLETE 55 /* listen state expires */ ++#define WLC_E_RSSI 56 /* indicate RSSI change based on configured levels */ ++#define WLC_E_PFN_SCAN_COMPLETE 57 /* PFN completed scan of network list */ ++#define WLC_E_EXTLOG_MSG 58 ++#define WLC_E_ACTION_FRAME 59 /* Action frame Rx */ ++#define WLC_E_ACTION_FRAME_COMPLETE 60 /* Action frame Tx complete */ ++#define WLC_E_PRE_ASSOC_IND 61 /* assoc request received */ ++#define WLC_E_PRE_REASSOC_IND 62 /* re-assoc request received */ ++#define WLC_E_CHANNEL_ADOPTED 63 ++#define WLC_E_AP_STARTED 64 /* AP started */ ++#define WLC_E_DFS_AP_STOP 65 /* AP stopped due to DFS */ ++#define WLC_E_DFS_AP_RESUME 66 /* AP resumed due to DFS */ ++#define WLC_E_WAI_STA_EVENT 67 /* WAI stations event */ ++#define WLC_E_WAI_MSG 68 /* event encapsulating an WAI message */ ++#define WLC_E_ESCAN_RESULT 69 /* escan result event */ ++#define WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE 70 /* action frame off channel complete */ ++#define WLC_E_PROBRESP_MSG 71 /* probe response received */ ++#define WLC_E_P2P_PROBREQ_MSG 72 /* P2P Probe request received */ ++#define WLC_E_DCS_REQUEST 73 ++ ++#define WLC_E_FIFO_CREDIT_MAP 74 /* credits for D11 FIFOs. [AC0,AC1,AC2,AC3,BC_MC,ATIM] */ ++ ++#define WLC_E_ACTION_FRAME_RX 75 /* Received action frame event WITH ++ * wl_event_rx_frame_data_t header ++ */ ++#define WLC_E_WAKE_EVENT 76 /* Wake Event timer fired, used for wake WLAN test mode */ ++#define WLC_E_RM_COMPLETE 77 /* Radio measurement complete */ ++#define WLC_E_HTSFSYNC 78 /* Synchronize TSF with the host */ ++#define WLC_E_OVERLAY_REQ 79 /* request an overlay IOCTL/iovar from the host */ ++#define WLC_E_CSA_COMPLETE_IND 80 /* 802.11 CHANNEL SWITCH ACTION completed */ ++#define WLC_E_EXCESS_PM_WAKE_EVENT 81 /* excess PM Wake Event to inform host */ ++#define WLC_E_PFN_SCAN_NONE 82 /* no PFN networks around */ ++#define WLC_E_PFN_SCAN_ALLGONE 83 /* last found PFN network gets lost */ ++#define WLC_E_GTK_PLUMBED 84 ++#define WLC_E_ASSOC_IND_NDIS 85 /* 802.11 ASSOC indication for NDIS only */ ++#define WLC_E_REASSOC_IND_NDIS 86 /* 802.11 REASSOC indication for NDIS only */ ++#define WLC_E_ASSOC_REQ_IE 87 ++#define WLC_E_ASSOC_RESP_IE 88 ++ ++#define WLC_E_LAST 89 /* highest val + 1 for range checking */ ++ ++/* Table of event name strings for UIs and debugging dumps */ ++typedef struct { ++ uint event; ++ const char *name; ++} bcmevent_name_t; ++ ++extern const bcmevent_name_t bcmevent_names[]; ++extern const int bcmevent_names_size; ++ ++/* Event status codes */ ++#define WLC_E_STATUS_SUCCESS 0 /* operation was successful */ ++#define WLC_E_STATUS_FAIL 1 /* operation failed */ ++#define WLC_E_STATUS_TIMEOUT 2 /* operation timed out */ ++#define WLC_E_STATUS_NO_NETWORKS 3 /* failed due to no matching network found */ ++#define WLC_E_STATUS_ABORT 4 /* operation was aborted */ ++#define WLC_E_STATUS_NO_ACK 5 /* protocol failure: packet not ack'd */ ++#define WLC_E_STATUS_UNSOLICITED 6 /* AUTH or ASSOC packet was unsolicited */ ++#define WLC_E_STATUS_ATTEMPT 7 /* attempt to assoc to an auto auth configuration */ ++#define WLC_E_STATUS_PARTIAL 8 /* scan results are incomplete */ ++#define WLC_E_STATUS_NEWSCAN 9 /* scan aborted by another scan */ ++#define WLC_E_STATUS_NEWASSOC 10 /* scan aborted due to assoc in progress */ ++#define WLC_E_STATUS_11HQUIET 11 /* 802.11h quiet period started */ ++#define WLC_E_STATUS_SUPPRESS 12 /* user disabled scanning (WLC_SET_SCANSUPPRESS) */ ++#define WLC_E_STATUS_NOCHANS 13 /* no allowable channels to scan */ ++#define WLC_E_STATUS_CS_ABORT 15 /* abort channel select */ ++#define WLC_E_STATUS_ERROR 16 /* request failed due to error */ ++ ++/* roam reason codes */ ++#define WLC_E_REASON_INITIAL_ASSOC 0 /* initial assoc */ ++#define WLC_E_REASON_LOW_RSSI 1 /* roamed due to low RSSI */ ++#define WLC_E_REASON_DEAUTH 2 /* roamed due to DEAUTH indication */ ++#define WLC_E_REASON_DISASSOC 3 /* roamed due to DISASSOC indication */ ++#define WLC_E_REASON_BCNS_LOST 4 /* roamed due to lost beacons */ ++#define WLC_E_REASON_MINTXRATE 9 /* roamed because at mintxrate for too long */ ++#define WLC_E_REASON_TXFAIL 10 /* We can hear AP, but AP can't hear us */ ++ ++/* Roam codes used primarily by CCX */ ++#define WLC_E_REASON_FAST_ROAM_FAILED 5 /* roamed due to fast roam failure */ ++#define WLC_E_REASON_DIRECTED_ROAM 6 /* roamed due to request by AP */ ++#define WLC_E_REASON_TSPEC_REJECTED 7 /* roamed due to TSPEC rejection */ ++#define WLC_E_REASON_BETTER_AP 8 /* roamed due to finding better AP */ ++ ++#define WLC_E_REASON_REQUESTED_ROAM 11 /* roamed due to BSS Mgmt Transition request by AP */ ++ ++/* prune reason codes */ ++#define WLC_E_PRUNE_ENCR_MISMATCH 1 /* encryption mismatch */ ++#define WLC_E_PRUNE_BCAST_BSSID 2 /* AP uses a broadcast BSSID */ ++#define WLC_E_PRUNE_MAC_DENY 3 /* STA's MAC addr is in AP's MAC deny list */ ++#define WLC_E_PRUNE_MAC_NA 4 /* STA's MAC addr is not in AP's MAC allow list */ ++#define WLC_E_PRUNE_REG_PASSV 5 /* AP not allowed due to regulatory restriction */ ++#define WLC_E_PRUNE_SPCT_MGMT 6 /* AP does not support STA locale spectrum mgmt */ ++#define WLC_E_PRUNE_RADAR 7 /* AP is on a radar channel of STA locale */ ++#define WLC_E_RSN_MISMATCH 8 /* STA does not support AP's RSN */ ++#define WLC_E_PRUNE_NO_COMMON_RATES 9 /* No rates in common with AP */ ++#define WLC_E_PRUNE_BASIC_RATES 10 /* STA does not support all basic rates of BSS */ ++#define WLC_E_PRUNE_CIPHER_NA 12 /* BSS's cipher not supported */ ++#define WLC_E_PRUNE_KNOWN_STA 13 /* AP is already known to us as a STA */ ++#define WLC_E_PRUNE_WDS_PEER 15 /* AP is already known to us as a WDS peer */ ++#define WLC_E_PRUNE_QBSS_LOAD 16 /* QBSS LOAD - AAC is too low */ ++#define WLC_E_PRUNE_HOME_AP 17 /* prune home AP */ ++ ++/* WPA failure reason codes carried in the WLC_E_PSK_SUP event */ ++#define WLC_E_SUP_OTHER 0 /* Other reason */ ++#define WLC_E_SUP_DECRYPT_KEY_DATA 1 /* Decryption of key data failed */ ++#define WLC_E_SUP_BAD_UCAST_WEP128 2 /* Illegal use of ucast WEP128 */ ++#define WLC_E_SUP_BAD_UCAST_WEP40 3 /* Illegal use of ucast WEP40 */ ++#define WLC_E_SUP_UNSUP_KEY_LEN 4 /* Unsupported key length */ ++#define WLC_E_SUP_PW_KEY_CIPHER 5 /* Unicast cipher mismatch in pairwise key */ ++#define WLC_E_SUP_MSG3_TOO_MANY_IE 6 /* WPA IE contains > 1 RSN IE in key msg 3 */ ++#define WLC_E_SUP_MSG3_IE_MISMATCH 7 /* WPA IE mismatch in key message 3 */ ++#define WLC_E_SUP_NO_INSTALL_FLAG 8 /* INSTALL flag unset in 4-way msg */ ++#define WLC_E_SUP_MSG3_NO_GTK 9 /* encapsulated GTK missing from msg 3 */ ++#define WLC_E_SUP_GRP_KEY_CIPHER 10 /* Multicast cipher mismatch in group key */ ++#define WLC_E_SUP_GRP_MSG1_NO_GTK 11 /* encapsulated GTK missing from group msg 1 */ ++#define WLC_E_SUP_GTK_DECRYPT_FAIL 12 /* GTK decrypt failure */ ++#define WLC_E_SUP_SEND_FAIL 13 /* message send failure */ ++#define WLC_E_SUP_DEAUTH 14 /* received FC_DEAUTH */ ++#define WLC_E_SUP_WPA_PSK_TMO 15 /* WPA PSK 4-way handshake timeout */ ++ ++/* Event data for events that include frames received over the air */ ++/* WLC_E_PROBRESP_MSG ++ * WLC_E_P2P_PROBREQ_MSG ++ * WLC_E_ACTION_FRAME_RX ++ */ ++typedef BWL_PRE_PACKED_STRUCT struct wl_event_rx_frame_data { ++ uint16 version; ++ uint16 channel; /* Matches chanspec_t format from bcmwifi_channels.h */ ++ int32 rssi; ++ uint32 mactime; ++ uint32 rate; ++} BWL_POST_PACKED_STRUCT wl_event_rx_frame_data_t; ++ ++#define BCM_RX_FRAME_DATA_VERSION 1 ++ ++/* WLC_E_IF event data */ ++typedef struct wl_event_data_if { ++ uint8 ifidx; /* RTE virtual device index (for dongle) */ ++ uint8 opcode; /* see I/F opcode */ ++ uint8 reserved; ++ uint8 bssidx; /* bsscfg index */ ++ uint8 role; /* see I/F role */ ++} wl_event_data_if_t; ++ ++/* opcode in WLC_E_IF event */ ++#define WLC_E_IF_ADD 1 /* bsscfg add */ ++#define WLC_E_IF_DEL 2 /* bsscfg delete */ ++#define WLC_E_IF_CHANGE 3 /* bsscfg role change */ ++ ++/* I/F role code in WLC_E_IF event */ ++#define WLC_E_IF_ROLE_STA 0 /* Infra STA */ ++#define WLC_E_IF_ROLE_AP 1 /* Access Point */ ++#define WLC_E_IF_ROLE_WDS 2 /* WDS link */ ++#define WLC_E_IF_ROLE_P2P_GO 3 /* P2P Group Owner */ ++#define WLC_E_IF_ROLE_P2P_CLIENT 4 /* P2P Client */ ++ ++/* Reason codes for LINK */ ++#define WLC_E_LINK_BCN_LOSS 1 /* Link down because of beacon loss */ ++#define WLC_E_LINK_DISASSOC 2 /* Link down because of disassoc */ ++#define WLC_E_LINK_ASSOC_REC 3 /* Link down because assoc recreate failed */ ++#define WLC_E_LINK_BSSCFG_DIS 4 /* Link down due to bsscfg down */ ++ ++/* reason codes for WLC_E_OVERLAY_REQ event */ ++#define WLC_E_OVL_DOWNLOAD 0 /* overlay download request */ ++#define WLC_E_OVL_UPDATE_IND 1 /* device indication of host overlay update */ ++ ++/* This marks the end of a packed structure section. */ ++#include ++ ++#endif /* _BCMEVENT_H_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/proto/bcmip.h b/drivers/net/ethernet/broadcom/gmac/src/include/proto/bcmip.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/proto/bcmip.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/proto/bcmip.h 2017-11-09 17:53:43.989292000 +0800 +@@ -0,0 +1,205 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Fundamental constants relating to IP Protocol ++ * ++ * $Id: bcmip.h 324300 2012-03-28 20:29:37Z $ ++ */ ++ ++#ifndef _bcmip_h_ ++#define _bcmip_h_ ++ ++#ifndef _TYPEDEFS_H_ ++#include ++#endif ++ ++/* This marks the start of a packed structure section. */ ++#include ++ ++ ++/* IPV4 and IPV6 common */ ++#define IP_VER_OFFSET 0x0 /* offset to version field */ ++#define IP_VER_MASK 0xf0 /* version mask */ ++#define IP_VER_SHIFT 4 /* version shift */ ++#define IP_VER_4 4 /* version number for IPV4 */ ++#define IP_VER_6 6 /* version number for IPV6 */ ++ ++#define IP_VER(ip_body) \ ++ ((((uint8 *)(ip_body))[IP_VER_OFFSET] & IP_VER_MASK) >> IP_VER_SHIFT) ++ ++#define IP_PROT_ICMP 0x1 /* ICMP protocol */ ++#define IP_PROT_IGMP 0x2 /* IGMP protocol */ ++#define IP_PROT_TCP 0x6 /* TCP protocol */ ++#define IP_PROT_UDP 0x11 /* UDP protocol type */ ++#define IP_PROT_ICMP6 0x3a /* ICMPv6 protocol type */ ++ ++/* IPV4 field offsets */ ++#define IPV4_VER_HL_OFFSET 0 /* version and ihl byte offset */ ++#define IPV4_TOS_OFFSET 1 /* type of service offset */ ++#define IPV4_PKTLEN_OFFSET 2 /* packet length offset */ ++#define IPV4_PKTFLAG_OFFSET 6 /* more-frag,dont-frag flag offset */ ++#define IPV4_PROT_OFFSET 9 /* protocol type offset */ ++#define IPV4_CHKSUM_OFFSET 10 /* IP header checksum offset */ ++#define IPV4_SRC_IP_OFFSET 12 /* src IP addr offset */ ++#define IPV4_DEST_IP_OFFSET 16 /* dest IP addr offset */ ++#define IPV4_OPTIONS_OFFSET 20 /* IP options offset */ ++#define IPV4_MIN_HEADER_LEN 20 /* Minimum size for an IP header (no options) */ ++ ++/* IPV4 field decodes */ ++#define IPV4_VER_MASK 0xf0 /* IPV4 version mask */ ++#define IPV4_VER_SHIFT 4 /* IPV4 version shift */ ++ ++#define IPV4_HLEN_MASK 0x0f /* IPV4 header length mask */ ++#define IPV4_HLEN(ipv4_body) (4 * (((uint8 *)(ipv4_body))[IPV4_VER_HL_OFFSET] & IPV4_HLEN_MASK)) ++ ++#define IPV4_ADDR_LEN 4 /* IPV4 address length */ ++ ++#define IPV4_ADDR_NULL(a) ((((uint8 *)(a))[0] | ((uint8 *)(a))[1] | \ ++ ((uint8 *)(a))[2] | ((uint8 *)(a))[3]) == 0) ++ ++#define IPV4_ADDR_BCAST(a) ((((uint8 *)(a))[0] & ((uint8 *)(a))[1] & \ ++ ((uint8 *)(a))[2] & ((uint8 *)(a))[3]) == 0xff) ++ ++#define IPV4_TOS_DSCP_MASK 0xfc /* DiffServ codepoint mask */ ++#define IPV4_TOS_DSCP_SHIFT 2 /* DiffServ codepoint shift */ ++ ++#define IPV4_TOS(ipv4_body) (((uint8 *)(ipv4_body))[IPV4_TOS_OFFSET]) ++ ++#define IPV4_TOS_PREC_MASK 0xe0 /* Historical precedence mask */ ++#define IPV4_TOS_PREC_SHIFT 5 /* Historical precedence shift */ ++ ++#define IPV4_TOS_LOWDELAY 0x10 /* Lowest delay requested */ ++#define IPV4_TOS_THROUGHPUT 0x8 /* Best throughput requested */ ++#define IPV4_TOS_RELIABILITY 0x4 /* Most reliable delivery requested */ ++ ++#define IPV4_PROT(ipv4_body) (((uint8 *)(ipv4_body))[IPV4_PROT_OFFSET]) ++ ++#define IPV4_FRAG_RESV 0x8000 /* Reserved */ ++#define IPV4_FRAG_DONT 0x4000 /* Don't fragment */ ++#define IPV4_FRAG_MORE 0x2000 /* More fragments */ ++#define IPV4_FRAG_OFFSET_MASK 0x1fff /* Fragment offset */ ++ ++#define IPV4_ADDR_STR_LEN 16 /* Max IP address length in string format */ ++ ++/* IPV4 packet formats */ ++BWL_PRE_PACKED_STRUCT struct ipv4_addr { ++ uint8 addr[IPV4_ADDR_LEN]; ++} BWL_POST_PACKED_STRUCT; ++ ++BWL_PRE_PACKED_STRUCT struct ipv4_hdr { ++ uint8 version_ihl; /* Version and Internet Header Length */ ++ uint8 tos; /* Type Of Service */ ++ uint16 tot_len; /* Number of bytes in packet (max 65535) */ ++ uint16 id; ++ uint16 frag; /* 3 flag bits and fragment offset */ ++ uint8 ttl; /* Time To Live */ ++ uint8 prot; /* Protocol */ ++ uint16 hdr_chksum; /* IP header checksum */ ++ uint8 src_ip[IPV4_ADDR_LEN]; /* Source IP Address */ ++ uint8 dst_ip[IPV4_ADDR_LEN]; /* Destination IP Address */ ++} BWL_POST_PACKED_STRUCT; ++ ++/* IPV6 field offsets */ ++#define IPV6_PAYLOAD_LEN_OFFSET 4 /* payload length offset */ ++#define IPV6_NEXT_HDR_OFFSET 6 /* next header/protocol offset */ ++#define IPV6_HOP_LIMIT_OFFSET 7 /* hop limit offset */ ++#define IPV6_SRC_IP_OFFSET 8 /* src IP addr offset */ ++#define IPV6_DEST_IP_OFFSET 24 /* dst IP addr offset */ ++ ++/* IPV6 field decodes */ ++#define IPV6_TRAFFIC_CLASS(ipv6_body) \ ++ (((((uint8 *)(ipv6_body))[0] & 0x0f) << 4) | \ ++ ((((uint8 *)(ipv6_body))[1] & 0xf0) >> 4)) ++ ++#define IPV6_FLOW_LABEL(ipv6_body) \ ++ (((((uint8 *)(ipv6_body))[1] & 0x0f) << 16) | \ ++ (((uint8 *)(ipv6_body))[2] << 8) | \ ++ (((uint8 *)(ipv6_body))[3])) ++ ++#define IPV6_PAYLOAD_LEN(ipv6_body) \ ++ ((((uint8 *)(ipv6_body))[IPV6_PAYLOAD_LEN_OFFSET + 0] << 8) | \ ++ ((uint8 *)(ipv6_body))[IPV6_PAYLOAD_LEN_OFFSET + 1]) ++ ++#define IPV6_NEXT_HDR(ipv6_body) \ ++ (((uint8 *)(ipv6_body))[IPV6_NEXT_HDR_OFFSET]) ++ ++#define IPV6_PROT(ipv6_body) IPV6_NEXT_HDR(ipv6_body) ++ ++#define IPV6_ADDR_LEN 16 /* IPV6 address length */ ++ ++/* IPV4 TOS or IPV6 Traffic Classifier or 0 */ ++#define IP_TOS46(ip_body) \ ++ (IP_VER(ip_body) == IP_VER_4 ? IPV4_TOS(ip_body) : \ ++ IP_VER(ip_body) == IP_VER_6 ? IPV6_TRAFFIC_CLASS(ip_body) : 0) ++ ++/* IPV6 extension headers (options) */ ++#define IPV6_EXTHDR_HOP 0 ++#define IPV6_EXTHDR_ROUTING 43 ++#define IPV6_EXTHDR_FRAGMENT 44 ++#define IPV6_EXTHDR_AUTH 51 ++#define IPV6_EXTHDR_NONE 59 ++#define IPV6_EXTHDR_DEST 60 ++ ++#define IPV6_EXTHDR(prot) (((prot) == IPV6_EXTHDR_HOP) || \ ++ ((prot) == IPV6_EXTHDR_ROUTING) || \ ++ ((prot) == IPV6_EXTHDR_FRAGMENT) || \ ++ ((prot) == IPV6_EXTHDR_AUTH) || \ ++ ((prot) == IPV6_EXTHDR_NONE) || \ ++ ((prot) == IPV6_EXTHDR_DEST)) ++ ++#define IPV6_MIN_HLEN 40 ++ ++#define IPV6_EXTHDR_LEN(eh) ((((struct ipv6_exthdr *)(eh))->hdrlen + 1) << 3) ++ ++BWL_PRE_PACKED_STRUCT struct ipv6_exthdr { ++ uint8 nexthdr; ++ uint8 hdrlen; ++} BWL_POST_PACKED_STRUCT; ++ ++BWL_PRE_PACKED_STRUCT struct ipv6_exthdr_frag { ++ uint8 nexthdr; ++ uint8 rsvd; ++ uint16 frag_off; ++ uint32 ident; ++} BWL_POST_PACKED_STRUCT; ++ ++static INLINE int32 ++ipv6_exthdr_len(uint8 *h, uint8 *proto) ++{ ++ uint16 len = 0, hlen; ++ struct ipv6_exthdr *eh = (struct ipv6_exthdr *)h; ++ ++ while (IPV6_EXTHDR(eh->nexthdr)) { ++ if (eh->nexthdr == IPV6_EXTHDR_NONE) ++ return -1; ++ else if (eh->nexthdr == IPV6_EXTHDR_FRAGMENT) ++ hlen = 8; ++ else if (eh->nexthdr == IPV6_EXTHDR_AUTH) ++ hlen = (eh->hdrlen + 2) << 2; ++ else ++ hlen = IPV6_EXTHDR_LEN(eh); ++ ++ len += hlen; ++ eh = (struct ipv6_exthdr *)(h + len); ++ } ++ ++ *proto = eh->nexthdr; ++ return len; ++} ++ ++/* This marks the end of a packed structure section. */ ++#include ++ ++#endif /* _bcmip_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/proto/bcmipv6.h b/drivers/net/ethernet/broadcom/gmac/src/include/proto/bcmipv6.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/proto/bcmipv6.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/proto/bcmipv6.h 2017-11-09 17:53:43.990289000 +0800 +@@ -0,0 +1,101 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Fundamental constants relating to Neighbor Discovery Protocol ++ * ++ * $Id: bcmipv6.h 305568 2011-12-29 20:21:17Z $ ++ */ ++ ++#ifndef _bcmipv6_h_ ++#define _bcmipv6_h_ ++ ++#ifndef _TYPEDEFS_H_ ++#include ++#endif ++ ++/* This marks the start of a packed structure section. */ ++#include ++ ++#define ICMPV6_HEADER_TYPE 0x3A ++#define ICMPV6_PKT_TYPE_NS 135 ++#define ICMPV6_PKT_TYPE_NA 136 ++ ++#define ICMPV6_ND_OPT_TYPE_TARGET_MAC 2 ++#define ICMPV6_ND_OPT_TYPE_SRC_MAC 1 ++ ++#define IPV6_VERSION 6 ++#define IPV6_HOP_LIMIT 255 ++ ++#define IPV6_ADDR_NULL(a) ((a[0] | a[1] | a[2] | a[3] | a[4] | \ ++ a[5] | a[6] | a[7] | a[8] | a[9] | \ ++ a[10] | a[11] | a[12] | a[13] | \ ++ a[14] | a[15]) == 0) ++ ++/* IPV6 address */ ++BWL_PRE_PACKED_STRUCT struct ipv6_addr { ++ uint8 addr[16]; ++} BWL_POST_PACKED_STRUCT; ++ ++#ifndef IL_BIGENDIAN ++ ++/* ICMPV6 Header */ ++BWL_PRE_PACKED_STRUCT struct icmp6_hdr { ++ uint8 icmp6_type; ++ uint8 icmp6_code; ++ uint16 icmp6_cksum; ++ BWL_PRE_PACKED_STRUCT union { ++ uint32 reserved; ++ BWL_PRE_PACKED_STRUCT struct nd_advt { ++ uint32 reserved1:5, ++ override:1, ++ solicited:1, ++ router:1, ++ reserved2:24; ++ } BWL_POST_PACKED_STRUCT nd_advt; ++ } BWL_POST_PACKED_STRUCT opt; ++} BWL_POST_PACKED_STRUCT; ++ ++/* Ipv6 Header Format */ ++BWL_PRE_PACKED_STRUCT struct ipv6_hdr { ++ uint8 priority:4, ++ version:4; ++ uint8 flow_lbl[3]; ++ uint16 payload_len; ++ uint8 nexthdr; ++ uint8 hop_limit; ++ struct ipv6_addr saddr; ++ struct ipv6_addr daddr; ++} BWL_POST_PACKED_STRUCT; ++ ++/* Neighbor Advertisement/Solicitation Packet Structure */ ++BWL_PRE_PACKED_STRUCT struct nd_msg { ++ struct icmp6_hdr icmph; ++ struct ipv6_addr target; ++} BWL_POST_PACKED_STRUCT; ++ ++ ++/* Neighibor Solicitation/Advertisement Optional Structure */ ++BWL_PRE_PACKED_STRUCT struct nd_msg_opt { ++ uint8 type; ++ uint8 len; ++ uint8 mac_addr[ETHER_ADDR_LEN]; ++} BWL_POST_PACKED_STRUCT; ++ ++#endif /* IL_BIGENDIAN */ ++ ++/* This marks the end of a packed structure section. */ ++#include ++ ++#endif /* !defined(_bcmipv6_h_) */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/proto/ethernet.h b/drivers/net/ethernet/broadcom/gmac/src/include/proto/ethernet.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/proto/ethernet.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/proto/ethernet.h 2017-11-09 17:53:43.991291000 +0800 +@@ -0,0 +1,202 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * From FreeBSD 2.2.7: Fundamental constants relating to ethernet. ++ * ++ * $Id: ethernet.h 316696 2012-02-23 03:29:35Z $ ++ */ ++ ++#ifndef _NET_ETHERNET_H_ /* use native BSD ethernet.h when available */ ++#define _NET_ETHERNET_H_ ++ ++#ifndef _TYPEDEFS_H_ ++#include "typedefs.h" ++#endif ++ ++/* This marks the start of a packed structure section. */ ++#include ++ ++ ++/* ++ * The number of bytes in an ethernet (MAC) address. ++ */ ++#define ETHER_ADDR_LEN 6 ++ ++/* ++ * The number of bytes in the type field. ++ */ ++#define ETHER_TYPE_LEN 2 ++ ++/* ++ * The number of bytes in the trailing CRC field. ++ */ ++#define ETHER_CRC_LEN 4 ++ ++/* ++ * The length of the combined header. ++ */ ++#define ETHER_HDR_LEN (ETHER_ADDR_LEN * 2 + ETHER_TYPE_LEN) ++ ++/* ++ * The minimum packet length. ++ */ ++#define ETHER_MIN_LEN 64 ++ ++/* ++ * The minimum packet user data length. ++ */ ++#define ETHER_MIN_DATA 46 ++ ++/* ++ * The maximum packet length. ++ */ ++#define ETHER_MAX_LEN 1518 ++ ++/* ++ * The maximum packet user data length. ++ */ ++#define ETHER_MAX_DATA 1500 ++ ++/* ether types */ ++#define ETHER_TYPE_MIN 0x0600 /* Anything less than MIN is a length */ ++#define ETHER_TYPE_IP 0x0800 /* IP */ ++#define ETHER_TYPE_ARP 0x0806 /* ARP */ ++#define ETHER_TYPE_8021Q 0x8100 /* 802.1Q */ ++#define ETHER_TYPE_IPV6 0x86dd /* IPv6 */ ++#define ETHER_TYPE_BRCM 0x886c /* Broadcom Corp. */ ++#define ETHER_TYPE_802_1X 0x888e /* 802.1x */ ++#define ETHER_TYPE_802_1X_PREAUTH 0x88c7 /* 802.1x preauthentication */ ++#define ETHER_TYPE_WAI 0x88b4 /* WAI */ ++#define ETHER_TYPE_89_0D 0x890d /* 89-0d frame for TDLS */ ++ ++#define ETHER_TYPE_PPP_SES 0x8864 /* PPPoE Session */ ++ ++/* Broadcom subtype follows ethertype; First 2 bytes are reserved; Next 2 are subtype; */ ++#define ETHER_BRCM_SUBTYPE_LEN 4 /* Broadcom 4 byte subtype */ ++ ++/* ether header */ ++#define ETHER_DEST_OFFSET (0 * ETHER_ADDR_LEN) /* dest address offset */ ++#define ETHER_SRC_OFFSET (1 * ETHER_ADDR_LEN) /* src address offset */ ++#define ETHER_TYPE_OFFSET (2 * ETHER_ADDR_LEN) /* ether type offset */ ++ ++/* ++ * A macro to validate a length with ++ */ ++#define ETHER_IS_VALID_LEN(foo) \ ++ ((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN) ++ ++#define ETHER_FILL_MCAST_ADDR_FROM_IP(ea, mgrp_ip) { \ ++ ((uint8 *)ea)[0] = 0x01; \ ++ ((uint8 *)ea)[1] = 0x00; \ ++ ((uint8 *)ea)[2] = 0x5e; \ ++ ((uint8 *)ea)[3] = ((mgrp_ip) >> 16) & 0x7f; \ ++ ((uint8 *)ea)[4] = ((mgrp_ip) >> 8) & 0xff; \ ++ ((uint8 *)ea)[5] = ((mgrp_ip) >> 0) & 0xff; \ ++} ++ ++#ifndef __INCif_etherh /* Quick and ugly hack for VxWorks */ ++/* ++ * Structure of a 10Mb/s Ethernet header. ++ */ ++BWL_PRE_PACKED_STRUCT struct ether_header { ++ uint8 ether_dhost[ETHER_ADDR_LEN]; ++ uint8 ether_shost[ETHER_ADDR_LEN]; ++ uint16 ether_type; ++} BWL_POST_PACKED_STRUCT; ++ ++/* ++ * Structure of a 48-bit Ethernet address. ++ */ ++BWL_PRE_PACKED_STRUCT struct ether_addr { ++ uint8 octet[ETHER_ADDR_LEN]; ++} BWL_POST_PACKED_STRUCT; ++#endif /* !__INCif_etherh Quick and ugly hack for VxWorks */ ++ ++/* ++ * Takes a pointer, set, test, clear, toggle locally admininistered ++ * address bit in the 48-bit Ethernet address. ++ */ ++#define ETHER_SET_LOCALADDR(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] | 2)) ++#define ETHER_IS_LOCALADDR(ea) (((uint8 *)(ea))[0] & 2) ++#define ETHER_CLR_LOCALADDR(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] & 0xfd)) ++#define ETHER_TOGGLE_LOCALADDR(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] ^ 2)) ++ ++/* Takes a pointer, marks unicast address bit in the MAC address */ ++#define ETHER_SET_UNICAST(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] & ~1)) ++ ++/* ++ * Takes a pointer, returns true if a 48-bit multicast address ++ * (including broadcast, since it is all ones) ++ */ ++#define ETHER_ISMULTI(ea) (((const uint8 *)(ea))[0] & 1) ++ ++/* Copy an ethernet address in reverse order */ ++#define ether_rcopy(s, d) \ ++do { \ ++ ((uint16 *)(d))[2] = ((uint16 *)(s))[2]; \ ++ ((uint16 *)(d))[1] = ((uint16 *)(s))[1]; \ ++ ((uint16 *)(d))[0] = ((uint16 *)(s))[0]; \ ++} while (0) ++ ++/* compare two ethernet addresses - assumes the pointers can be referenced as shorts */ ++#define eacmp(a, b) ((((uint16 *)(a))[0] ^ ((uint16 *)(b))[0]) | \ ++ (((uint16 *)(a))[1] ^ ((uint16 *)(b))[1]) | \ ++ (((uint16 *)(a))[2] ^ ((uint16 *)(b))[2])) ++ ++#define ether_cmp(a, b) eacmp(a, b) ++ ++/* copy an ethernet address - assumes the pointers can be referenced as shorts */ ++#define eacopy(s, d) \ ++do { \ ++ ((uint16 *)(d))[0] = ((const uint16 *)(s))[0]; \ ++ ((uint16 *)(d))[1] = ((const uint16 *)(s))[1]; \ ++ ((uint16 *)(d))[2] = ((const uint16 *)(s))[2]; \ ++} while (0) ++ ++#define ether_copy(s, d) eacopy(s, d) ++ ++ ++static const struct ether_addr ether_bcast = {{255, 255, 255, 255, 255, 255}}; ++static const struct ether_addr ether_null = {{0, 0, 0, 0, 0, 0}}; ++ ++#define ETHER_ISBCAST(ea) ((((const uint8 *)(ea))[0] & \ ++ ((const uint8 *)(ea))[1] & \ ++ ((const uint8 *)(ea))[2] & \ ++ ((const uint8 *)(ea))[3] & \ ++ ((const uint8 *)(ea))[4] & \ ++ ((const uint8 *)(ea))[5]) == 0xff) ++#define ETHER_ISNULLADDR(ea) ((((const uint8 *)(ea))[0] | \ ++ ((const uint8 *)(ea))[1] | \ ++ ((const uint8 *)(ea))[2] | \ ++ ((const uint8 *)(ea))[3] | \ ++ ((const uint8 *)(ea))[4] | \ ++ ((const uint8 *)(ea))[5]) == 0) ++ ++#define ETHER_ISNULLDEST(da) ((((const uint16 *)(da))[0] | \ ++ ((const uint16 *)(da))[1] | \ ++ ((const uint16 *)(da))[2]) == 0) ++ ++ ++#define ETHER_MOVE_HDR(d, s) \ ++do { \ ++ struct ether_header t; \ ++ t = *(struct ether_header *)(s); \ ++ *(struct ether_header *)(d) = t; \ ++} while (0) ++ ++/* This marks the end of a packed structure section. */ ++#include ++ ++#endif /* _NET_ETHERNET_H_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/proto/vlan.h b/drivers/net/ethernet/broadcom/gmac/src/include/proto/vlan.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/proto/vlan.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/proto/vlan.h 2017-11-09 17:53:43.991302000 +0800 +@@ -0,0 +1,67 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * 802.1Q VLAN protocol definitions ++ * ++ * $Id: vlan.h 241182 2011-02-17 21:50:03Z $ ++ */ ++ ++#ifndef _vlan_h_ ++#define _vlan_h_ ++ ++#ifndef _TYPEDEFS_H_ ++#include ++#endif ++ ++/* This marks the start of a packed structure section. */ ++#include ++ ++#ifndef VLAN_VID_MASK ++#define VLAN_VID_MASK 0xfff /* low 12 bits are vlan id */ ++#endif ++#define VLAN_CFI_SHIFT 12 /* canonical format indicator bit */ ++#define VLAN_PRI_SHIFT 13 /* user priority */ ++ ++#define VLAN_PRI_MASK 7 /* 3 bits of priority */ ++ ++#define VLAN_TCI_OFFSET 14 /* offset of tag ctrl info field */ ++ ++#define VLAN_TAG_LEN 4 ++#define VLAN_TAG_OFFSET (2 * ETHER_ADDR_LEN) /* offset in Ethernet II packet only */ ++ ++#define VLAN_TPID 0x8100 /* VLAN ethertype/Tag Protocol ID */ ++ ++struct ethervlan_header { ++ uint8 ether_dhost[ETHER_ADDR_LEN]; ++ uint8 ether_shost[ETHER_ADDR_LEN]; ++ uint16 vlan_type; /* 0x8100 */ ++ uint16 vlan_tag; /* priority, cfi and vid */ ++ uint16 ether_type; ++}; ++ ++#define ETHERVLAN_HDR_LEN (ETHER_HDR_LEN + VLAN_TAG_LEN) ++ ++ ++/* This marks the end of a packed structure section. */ ++#include ++ ++#define ETHERVLAN_MOVE_HDR(d, s) \ ++do { \ ++ struct ethervlan_header t; \ ++ t = *(struct ethervlan_header *)(s); \ ++ *(struct ethervlan_header *)(d) = t; \ ++} while (0) ++ ++#endif /* _vlan_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/proto/wpa.h b/drivers/net/ethernet/broadcom/gmac/src/include/proto/wpa.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/proto/wpa.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/proto/wpa.h 2017-11-09 17:53:43.992308000 +0800 +@@ -0,0 +1,169 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Fundamental types and constants relating to WPA ++ * ++ * $Id: wpa.h 261155 2011-05-23 23:51:32Z $ ++ */ ++ ++#ifndef _proto_wpa_h_ ++#define _proto_wpa_h_ ++ ++#include ++#include ++ ++ ++/* This marks the start of a packed structure section. */ ++#include ++ ++/* Reason Codes */ ++ ++/* 13 through 23 taken from IEEE Std 802.11i-2004 */ ++#define DOT11_RC_INVALID_WPA_IE 13 /* Invalid info. element */ ++#define DOT11_RC_MIC_FAILURE 14 /* Michael failure */ ++#define DOT11_RC_4WH_TIMEOUT 15 /* 4-way handshake timeout */ ++#define DOT11_RC_GTK_UPDATE_TIMEOUT 16 /* Group key update timeout */ ++#define DOT11_RC_WPA_IE_MISMATCH 17 /* WPA IE in 4-way handshake differs from ++ * (re-)assoc. request/probe response ++ */ ++#define DOT11_RC_INVALID_MC_CIPHER 18 /* Invalid multicast cipher */ ++#define DOT11_RC_INVALID_UC_CIPHER 19 /* Invalid unicast cipher */ ++#define DOT11_RC_INVALID_AKMP 20 /* Invalid authenticated key management protocol */ ++#define DOT11_RC_BAD_WPA_VERSION 21 /* Unsupported WPA version */ ++#define DOT11_RC_INVALID_WPA_CAP 22 /* Invalid WPA IE capabilities */ ++#define DOT11_RC_8021X_AUTH_FAIL 23 /* 802.1X authentication failure */ ++ ++#define WPA2_PMKID_LEN 16 ++ ++/* WPA IE fixed portion */ ++typedef BWL_PRE_PACKED_STRUCT struct ++{ ++ uint8 tag; /* TAG */ ++ uint8 length; /* TAG length */ ++ uint8 oui[3]; /* IE OUI */ ++ uint8 oui_type; /* OUI type */ ++ BWL_PRE_PACKED_STRUCT struct { ++ uint8 low; ++ uint8 high; ++ } BWL_POST_PACKED_STRUCT version; /* IE version */ ++} BWL_POST_PACKED_STRUCT wpa_ie_fixed_t; ++#define WPA_IE_OUITYPE_LEN 4 ++#define WPA_IE_FIXED_LEN 8 ++#define WPA_IE_TAG_FIXED_LEN 6 ++ ++typedef BWL_PRE_PACKED_STRUCT struct { ++ uint8 tag; /* TAG */ ++ uint8 length; /* TAG length */ ++ BWL_PRE_PACKED_STRUCT struct { ++ uint8 low; ++ uint8 high; ++ } BWL_POST_PACKED_STRUCT version; /* IE version */ ++} BWL_POST_PACKED_STRUCT wpa_rsn_ie_fixed_t; ++#define WPA_RSN_IE_FIXED_LEN 4 ++#define WPA_RSN_IE_TAG_FIXED_LEN 2 ++typedef uint8 wpa_pmkid_t[WPA2_PMKID_LEN]; ++ ++/* WPA suite/multicast suite */ ++typedef BWL_PRE_PACKED_STRUCT struct ++{ ++ uint8 oui[3]; ++ uint8 type; ++} BWL_POST_PACKED_STRUCT wpa_suite_t, wpa_suite_mcast_t; ++#define WPA_SUITE_LEN 4 ++ ++/* WPA unicast suite list/key management suite list */ ++typedef BWL_PRE_PACKED_STRUCT struct ++{ ++ BWL_PRE_PACKED_STRUCT struct { ++ uint8 low; ++ uint8 high; ++ } BWL_POST_PACKED_STRUCT count; ++ wpa_suite_t list[1]; ++} BWL_POST_PACKED_STRUCT wpa_suite_ucast_t, wpa_suite_auth_key_mgmt_t; ++#define WPA_IE_SUITE_COUNT_LEN 2 ++typedef BWL_PRE_PACKED_STRUCT struct ++{ ++ BWL_PRE_PACKED_STRUCT struct { ++ uint8 low; ++ uint8 high; ++ } BWL_POST_PACKED_STRUCT count; ++ wpa_pmkid_t list[1]; ++} BWL_POST_PACKED_STRUCT wpa_pmkid_list_t; ++ ++/* WPA cipher suites */ ++#define WPA_CIPHER_NONE 0 /* None */ ++#define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */ ++#define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */ ++#define WPA_CIPHER_AES_OCB 3 /* AES (OCB) */ ++#define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */ ++#define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */ ++#define WPA_CIPHER_BIP 6 /* WEP (104-bit) */ ++#define WPA_CIPHER_TPK 7 /* Group addressed traffic not allowed */ ++ ++ ++#define IS_WPA_CIPHER(cipher) ((cipher) == WPA_CIPHER_NONE || \ ++ (cipher) == WPA_CIPHER_WEP_40 || \ ++ (cipher) == WPA_CIPHER_WEP_104 || \ ++ (cipher) == WPA_CIPHER_TKIP || \ ++ (cipher) == WPA_CIPHER_AES_OCB || \ ++ (cipher) == WPA_CIPHER_AES_CCM || \ ++ (cipher) == WPA_CIPHER_TPK) ++ ++ ++/* WPA TKIP countermeasures parameters */ ++#define WPA_TKIP_CM_DETECT 60 /* multiple MIC failure window (seconds) */ ++#define WPA_TKIP_CM_BLOCK 60 /* countermeasures active window (seconds) */ ++ ++/* RSN IE defines */ ++#define RSN_CAP_LEN 2 /* Length of RSN capabilities field (2 octets) */ ++ ++/* RSN Capabilities defined in 802.11i */ ++#define RSN_CAP_PREAUTH 0x0001 ++#define RSN_CAP_NOPAIRWISE 0x0002 ++#define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C ++#define RSN_CAP_PTK_REPLAY_CNTR_SHIFT 2 ++#define RSN_CAP_GTK_REPLAY_CNTR_MASK 0x0030 ++#define RSN_CAP_GTK_REPLAY_CNTR_SHIFT 4 ++#define RSN_CAP_1_REPLAY_CNTR 0 ++#define RSN_CAP_2_REPLAY_CNTRS 1 ++#define RSN_CAP_4_REPLAY_CNTRS 2 ++#define RSN_CAP_16_REPLAY_CNTRS 3 ++#ifdef MFP ++#define RSN_CAP_MFPR 0x0040 ++#define RSN_CAP_MFPC 0x0080 ++#endif ++ ++/* WPA capabilities defined in 802.11i */ ++#define WPA_CAP_4_REPLAY_CNTRS RSN_CAP_4_REPLAY_CNTRS ++#define WPA_CAP_16_REPLAY_CNTRS RSN_CAP_16_REPLAY_CNTRS ++#define WPA_CAP_REPLAY_CNTR_SHIFT RSN_CAP_PTK_REPLAY_CNTR_SHIFT ++#define WPA_CAP_REPLAY_CNTR_MASK RSN_CAP_PTK_REPLAY_CNTR_MASK ++ ++/* WPA capabilities defined in 802.11zD9.0 */ ++#define WPA_CAP_PEER_KEY_ENABLE (0x1 << 1) /* bit 9 */ ++ ++/* WPA Specific defines */ ++#define WPA_CAP_LEN RSN_CAP_LEN /* Length of RSN capabilities in RSN IE (2 octets) */ ++#define WPA_PMKID_CNT_LEN 2 /* Length of RSN PMKID count (2 octests) */ ++ ++#define WPA_CAP_WPA2_PREAUTH RSN_CAP_PREAUTH ++ ++#define WPA2_PMKID_COUNT_LEN 2 ++ ++ ++/* This marks the end of a packed structure section. */ ++#include ++ ++#endif /* _proto_wpa_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/sbchipc.h b/drivers/net/ethernet/broadcom/gmac/src/include/sbchipc.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/sbchipc.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/sbchipc.h 2017-11-09 17:53:44.004291000 +0800 +@@ -0,0 +1,2515 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * SiliconBackplane Chipcommon core hardware definitions. ++ * ++ * The chipcommon core provides chip identification, SB control, ++ * JTAG, 0/1/2 UARTs, clock frequency control, a watchdog interrupt timer, ++ * GPIO interface, extbus, and support for serial and parallel flashes. ++ * ++ * $Id: sbchipc.h 328955 2012-04-23 09:06:12Z $ ++ */ ++ ++#ifndef _SBCHIPC_H ++#define _SBCHIPC_H ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif /* PAD */ ++ ++typedef struct eci_prerev35 { ++ uint32 eci_output; ++ uint32 eci_control; ++ uint32 eci_inputlo; ++ uint32 eci_inputmi; ++ uint32 eci_inputhi; ++ uint32 eci_inputintpolaritylo; ++ uint32 eci_inputintpolaritymi; ++ uint32 eci_inputintpolarityhi; ++ uint32 eci_intmasklo; ++ uint32 eci_intmaskmi; ++ uint32 eci_intmaskhi; ++ uint32 eci_eventlo; ++ uint32 eci_eventmi; ++ uint32 eci_eventhi; ++ uint32 eci_eventmasklo; ++ uint32 eci_eventmaskmi; ++ uint32 eci_eventmaskhi; ++ uint32 PAD[3]; ++} eci_prerev35_t; ++ ++typedef struct eci_rev35 { ++ uint32 eci_outputlo; ++ uint32 eci_outputhi; ++ uint32 eci_controllo; ++ uint32 eci_controlhi; ++ uint32 eci_inputlo; ++ uint32 eci_inputhi; ++ uint32 eci_inputintpolaritylo; ++ uint32 eci_inputintpolarityhi; ++ uint32 eci_intmasklo; ++ uint32 eci_intmaskhi; ++ uint32 eci_eventlo; ++ uint32 eci_eventhi; ++ uint32 eci_eventmasklo; ++ uint32 eci_eventmaskhi; ++ uint32 eci_auxtx; ++ uint32 eci_auxrx; ++ uint32 eci_datatag; ++ uint32 eci_uartescvalue; ++ uint32 eci_autobaudctr; ++ uint32 eci_uartfifolevel; ++} eci_rev35_t; ++ ++typedef struct flash_config { ++ uint32 PAD[19]; ++ /* Flash struct configuration registers (0x18c) for BCM4706 (corerev = 31) */ ++ uint32 flashstrconfig; ++} flash_config_t; ++ ++typedef volatile struct { ++ uint32 chipid; /* 0x0 */ ++ uint32 capabilities; ++ uint32 corecontrol; /* corerev >= 1 */ ++ uint32 bist; ++ ++ /* OTP */ ++ uint32 otpstatus; /* 0x10, corerev >= 10 */ ++ uint32 otpcontrol; ++ uint32 otpprog; ++ uint32 otplayout; /* corerev >= 23 */ ++ ++ /* Interrupt control */ ++ uint32 intstatus; /* 0x20 */ ++ uint32 intmask; ++ ++ /* Chip specific regs */ ++ uint32 chipcontrol; /* 0x28, rev >= 11 */ ++ uint32 chipstatus; /* 0x2c, rev >= 11 */ ++ ++ /* Jtag Master */ ++ uint32 jtagcmd; /* 0x30, rev >= 10 */ ++ uint32 jtagir; ++ uint32 jtagdr; ++ uint32 jtagctrl; ++ ++ /* serial flash interface registers */ ++ uint32 flashcontrol; /* 0x40 */ ++ uint32 flashaddress; ++ uint32 flashdata; ++ uint32 otplayoutextension; /* rev >= 35 */ ++ ++ /* Silicon backplane configuration broadcast control */ ++ uint32 broadcastaddress; /* 0x50 */ ++ uint32 broadcastdata; ++ ++ /* gpio - cleared only by power-on-reset */ ++ uint32 gpiopullup; /* 0x58, corerev >= 20 */ ++ uint32 gpiopulldown; /* 0x5c, corerev >= 20 */ ++ uint32 gpioin; /* 0x60 */ ++ uint32 gpioout; /* 0x64 */ ++ uint32 gpioouten; /* 0x68 */ ++ uint32 gpiocontrol; /* 0x6C */ ++ uint32 gpiointpolarity; /* 0x70 */ ++ uint32 gpiointmask; /* 0x74 */ ++ ++ /* GPIO events corerev >= 11 */ ++ uint32 gpioevent; ++ uint32 gpioeventintmask; ++ ++ /* Watchdog timer */ ++ uint32 watchdog; /* 0x80 */ ++ ++ /* GPIO events corerev >= 11 */ ++ uint32 gpioeventintpolarity; ++ ++ /* GPIO based LED powersave registers corerev >= 16 */ ++ uint32 gpiotimerval; /* 0x88 */ ++ uint32 gpiotimeroutmask; ++ ++ /* clock control */ ++ uint32 clockcontrol_n; /* 0x90 */ ++ uint32 clockcontrol_sb; /* aka m0 */ ++ uint32 clockcontrol_pci; /* aka m1 */ ++ uint32 clockcontrol_m2; /* mii/uart/mipsref */ ++ uint32 clockcontrol_m3; /* cpu */ ++ uint32 clkdiv; /* corerev >= 3 */ ++ uint32 gpiodebugsel; /* corerev >= 28 */ ++ uint32 capabilities_ext; /* 0xac */ ++ ++ /* pll delay registers (corerev >= 4) */ ++ uint32 pll_on_delay; /* 0xb0 */ ++ uint32 fref_sel_delay; ++ uint32 slow_clk_ctl; /* 5 < corerev < 10 */ ++ uint32 PAD; ++ ++ /* Instaclock registers (corerev >= 10) */ ++ uint32 system_clk_ctl; /* 0xc0 */ ++ uint32 clkstatestretch; ++ uint32 PAD[2]; ++ ++ /* Indirect backplane access (corerev >= 22) */ ++ uint32 bp_addrlow; /* 0xd0 */ ++ uint32 bp_addrhigh; ++ uint32 bp_data; ++ uint32 PAD; ++ uint32 bp_indaccess; ++ /* SPI registers, corerev >= 37 */ ++ uint32 gsioctrl; ++ uint32 gsioaddress; ++ uint32 gsiodata; ++ ++ /* More clock dividers (corerev >= 32) */ ++ uint32 clkdiv2; ++ /* FAB ID (corerev >= 40) */ ++ uint32 otpcontrol1; ++ uint32 fabid; /* 0xf8 */ ++ ++ /* In AI chips, pointer to erom */ ++ uint32 eromptr; /* 0xfc */ ++ ++ /* ExtBus control registers (corerev >= 3) */ ++ uint32 pcmcia_config; /* 0x100 */ ++ uint32 pcmcia_memwait; ++ uint32 pcmcia_attrwait; ++ uint32 pcmcia_iowait; ++ uint32 ide_config; ++ uint32 ide_memwait; ++ uint32 ide_attrwait; ++ uint32 ide_iowait; ++ uint32 prog_config; ++ uint32 prog_waitcount; ++ uint32 flash_config; ++ uint32 flash_waitcount; ++ uint32 SECI_config; /* 0x130 SECI configuration */ ++ uint32 SECI_status; ++ uint32 SECI_statusmask; ++ uint32 SECI_rxnibchanged; ++ ++ union { /* 0x140 */ ++ /* Enhanced Coexistence Interface (ECI) registers (corerev >= 21) */ ++ struct eci_prerev35 lt35; ++ struct eci_rev35 ge35; ++ /* Other interfaces */ ++ struct flash_config flashconf; ++ uint32 PAD[20]; ++ } eci; ++ ++ /* SROM interface (corerev >= 32) */ ++ uint32 sromcontrol; /* 0x190 */ ++ uint32 sromaddress; ++ uint32 sromdata; ++ uint32 PAD[1]; /* 0x19C */ ++ /* NAND flash registers for BCM4706 (corerev = 31) */ ++ uint32 nflashctrl; /* 0x1a0 */ ++ uint32 nflashconf; ++ uint32 nflashcoladdr; ++ uint32 nflashrowaddr; ++ uint32 nflashdata; ++ uint32 nflashwaitcnt0; /* 0x1b4 */ ++ uint32 PAD[2]; ++ ++ uint32 seci_uart_data; /* 0x1C0 */ ++ uint32 seci_uart_bauddiv; ++ uint32 seci_uart_fcr; ++ uint32 seci_uart_lcr; ++ uint32 seci_uart_mcr; ++ uint32 seci_uart_lsr; ++ uint32 seci_uart_msr; ++ uint32 seci_uart_baudadj; ++ /* Clock control and hardware workarounds (corerev >= 20) */ ++ uint32 clk_ctl_st; /* 0x1e0 */ ++ uint32 hw_war; ++ uint32 PAD[70]; ++ ++ /* UARTs */ ++ uint8 uart0data; /* 0x300 */ ++ uint8 uart0imr; ++ uint8 uart0fcr; ++ uint8 uart0lcr; ++ uint8 uart0mcr; ++ uint8 uart0lsr; ++ uint8 uart0msr; ++ uint8 uart0scratch; ++ uint8 PAD[248]; /* corerev >= 1 */ ++ ++ uint8 uart1data; /* 0x400 */ ++ uint8 uart1imr; ++ uint8 uart1fcr; ++ uint8 uart1lcr; ++ uint8 uart1mcr; ++ uint8 uart1lsr; ++ uint8 uart1msr; ++ uint8 uart1scratch; ++ uint32 PAD[126]; ++ ++ /* PMU registers (corerev >= 20) */ ++ /* Note: all timers driven by ILP clock are updated asynchronously to HT/ALP. ++ * The CPU must read them twice, compare, and retry if different. ++ */ ++ uint32 pmucontrol; /* 0x600 */ ++ uint32 pmucapabilities; ++ uint32 pmustatus; ++ uint32 res_state; ++ uint32 res_pending; ++ uint32 pmutimer; ++ uint32 min_res_mask; ++ uint32 max_res_mask; ++ uint32 res_table_sel; ++ uint32 res_dep_mask; ++ uint32 res_updn_timer; ++ uint32 res_timer; ++ uint32 clkstretch; ++ uint32 pmuwatchdog; ++ uint32 gpiosel; /* 0x638, rev >= 1 */ ++ uint32 gpioenable; /* 0x63c, rev >= 1 */ ++ uint32 res_req_timer_sel; ++ uint32 res_req_timer; ++ uint32 res_req_mask; ++ uint32 PAD; ++ uint32 chipcontrol_addr; /* 0x650 */ ++ uint32 chipcontrol_data; /* 0x654 */ ++ uint32 regcontrol_addr; ++ uint32 regcontrol_data; ++ uint32 pllcontrol_addr; ++ uint32 pllcontrol_data; ++ uint32 pmustrapopt; /* 0x668, corerev >= 28 */ ++ uint32 pmu_xtalfreq; /* 0x66C, pmurev >= 10 */ ++ uint32 PAD[100]; ++ uint16 sromotp[512]; /* 0x800 */ ++#ifdef NFLASH_SUPPORT ++ /* Nand flash MLC controller registers (corerev >= 38) */ ++ uint32 nand_revision; /* 0xC00 */ ++ uint32 nand_cmd_start; ++ uint32 nand_cmd_addr_x; ++ uint32 nand_cmd_addr; ++ uint32 nand_cmd_end_addr; ++ uint32 nand_cs_nand_select; ++ uint32 nand_cs_nand_xor; ++ uint32 PAD; ++ uint32 nand_spare_rd0; ++ uint32 nand_spare_rd4; ++ uint32 nand_spare_rd8; ++ uint32 nand_spare_rd12; ++ uint32 nand_spare_wr0; ++ uint32 nand_spare_wr4; ++ uint32 nand_spare_wr8; ++ uint32 nand_spare_wr12; ++ uint32 nand_acc_control; ++ uint32 PAD; ++ uint32 nand_config; ++ uint32 PAD; ++ uint32 nand_timing_1; ++ uint32 nand_timing_2; ++ uint32 nand_semaphore; ++ uint32 PAD; ++ uint32 nand_devid; ++ uint32 nand_devid_x; ++ uint32 nand_block_lock_status; ++ uint32 nand_intfc_status; ++ uint32 nand_ecc_corr_addr_x; ++ uint32 nand_ecc_corr_addr; ++ uint32 nand_ecc_unc_addr_x; ++ uint32 nand_ecc_unc_addr; ++ uint32 nand_read_error_count; ++ uint32 nand_corr_stat_threshold; ++ uint32 PAD[2]; ++ uint32 nand_read_addr_x; ++ uint32 nand_read_addr; ++ uint32 nand_page_program_addr_x; ++ uint32 nand_page_program_addr; ++ uint32 nand_copy_back_addr_x; ++ uint32 nand_copy_back_addr; ++ uint32 nand_block_erase_addr_x; ++ uint32 nand_block_erase_addr; ++ uint32 nand_inv_read_addr_x; ++ uint32 nand_inv_read_addr; ++ uint32 PAD[2]; ++ uint32 nand_blk_wr_protect; ++ uint32 PAD[3]; ++ uint32 nand_acc_control_cs1; ++ uint32 nand_config_cs1; ++ uint32 nand_timing_1_cs1; ++ uint32 nand_timing_2_cs1; ++ uint32 PAD[20]; ++ uint32 nand_spare_rd16; ++ uint32 nand_spare_rd20; ++ uint32 nand_spare_rd24; ++ uint32 nand_spare_rd28; ++ uint32 nand_cache_addr; ++ uint32 nand_cache_data; ++ uint32 nand_ctrl_config; ++ uint32 nand_ctrl_status; ++#endif /* NFLASH_SUPPORT */ ++ uint32 gci_corecaps0; /* GCI starting at 0xC00 */ ++ uint32 gci_corecaps1; ++ uint32 gci_corecaps2; ++ uint32 gci_corectrl; ++ uint32 gci_corestat; /* 0xC10 */ ++ uint32 PAD[11]; ++ uint32 gci_indirect_addr; /* 0xC40 */ ++ uint32 PAD[111]; ++ uint32 gci_chipctrl; /* 0xE00 */ ++} chipcregs_t; ++ ++#endif /* _LANGUAGE_ASSEMBLY */ ++ ++#if defined(IL_BIGENDIAN) && defined(BCMHND74K) ++/* Selective swapped defines for those registers we need in ++ * big-endian code. ++ */ ++#define CC_CHIPID 4 ++#define CC_CAPABILITIES 0 ++#define CC_CHIPST 0x28 ++#define CC_EROMPTR 0xf8 ++ ++#else /* !IL_BIGENDIAN || !BCMHND74K */ ++ ++#define CC_CHIPID 0 ++#define CC_CAPABILITIES 4 ++#define CC_CHIPST 0x2c ++#define CC_EROMPTR 0xfc ++ ++#endif /* IL_BIGENDIAN && BCMHND74K */ ++ ++#define CC_OTPST 0x10 ++#define CC_JTAGCMD 0x30 ++#define CC_JTAGIR 0x34 ++#define CC_JTAGDR 0x38 ++#define CC_JTAGCTRL 0x3c ++#define CC_GPIOPU 0x58 ++#define CC_GPIOPD 0x5c ++#define CC_GPIOIN 0x60 ++#define CC_GPIOOUT 0x64 ++#define CC_GPIOOUTEN 0x68 ++#define CC_GPIOCTRL 0x6c ++#define CC_GPIOPOL 0x70 ++#define CC_GPIOINTM 0x74 ++#define CC_WATCHDOG 0x80 ++#define CC_CLKC_N 0x90 ++#define CC_CLKC_M0 0x94 ++#define CC_CLKC_M1 0x98 ++#define CC_CLKC_M2 0x9c ++#define CC_CLKC_M3 0xa0 ++#define CC_CLKDIV 0xa4 ++#define CC_SYS_CLK_CTL 0xc0 ++#define CC_CLK_CTL_ST SI_CLK_CTL_ST ++#define PMU_CTL 0x600 ++#define PMU_CAP 0x604 ++#define PMU_ST 0x608 ++#define PMU_RES_STATE 0x60c ++#define PMU_TIMER 0x614 ++#define PMU_MIN_RES_MASK 0x618 ++#define PMU_MAX_RES_MASK 0x61c ++#define CC_CHIPCTL_ADDR 0x650 ++#define CC_CHIPCTL_DATA 0x654 ++#define PMU_REG_CONTROL_ADDR 0x658 ++#define PMU_REG_CONTROL_DATA 0x65C ++#define PMU_PLL_CONTROL_ADDR 0x660 ++#define PMU_PLL_CONTROL_DATA 0x664 ++#define CC_SROM_CTRL 0x190 ++#define CC_SROM_OTP 0x800 /* SROM/OTP address space */ ++#define CC_GCI_INDIRECT_ADDR_REG 0xC40 ++#define CC_GCI_CHIP_CTRL_REG 0xE00 ++#define CC_GCI_CC_OFFSET_2 2 ++#define CC_GCI_CC_OFFSET_5 5 ++ ++#ifdef NFLASH_SUPPORT ++/* NAND flash support */ ++#define CC_NAND_REVISION 0xC00 ++#define CC_NAND_CMD_START 0xC04 ++#define CC_NAND_CMD_ADDR 0xC0C ++#define CC_NAND_SPARE_RD_0 0xC20 ++#define CC_NAND_SPARE_RD_4 0xC24 ++#define CC_NAND_SPARE_RD_8 0xC28 ++#define CC_NAND_SPARE_RD_C 0xC2C ++#define CC_NAND_CONFIG 0xC48 ++#define CC_NAND_DEVID 0xC60 ++#define CC_NAND_DEVID_EXT 0xC64 ++#define CC_NAND_INTFC_STATUS 0xC6C ++#endif /* NFLASH_SUPPORT */ ++ ++/* chipid */ ++#define CID_ID_MASK 0x0000ffff /* Chip Id mask */ ++#define CID_REV_MASK 0x000f0000 /* Chip Revision mask */ ++#define CID_REV_SHIFT 16 /* Chip Revision shift */ ++#define CID_PKG_MASK 0x00f00000 /* Package Option mask */ ++#define CID_PKG_SHIFT 20 /* Package Option shift */ ++#define CID_CC_MASK 0x0f000000 /* CoreCount (corerev >= 4) */ ++#define CID_CC_SHIFT 24 ++#define CID_TYPE_MASK 0xf0000000 /* Chip Type */ ++#define CID_TYPE_SHIFT 28 ++ ++/* capabilities */ ++#define CC_CAP_UARTS_MASK 0x00000003 /* Number of UARTs */ ++#define CC_CAP_MIPSEB 0x00000004 /* MIPS is in big-endian mode */ ++#define CC_CAP_UCLKSEL 0x00000018 /* UARTs clock select */ ++#define CC_CAP_UINTCLK 0x00000008 /* UARTs are driven by internal divided clock */ ++#define CC_CAP_UARTGPIO 0x00000020 /* UARTs own GPIOs 15:12 */ ++#define CC_CAP_EXTBUS_MASK 0x000000c0 /* External bus mask */ ++#define CC_CAP_EXTBUS_NONE 0x00000000 /* No ExtBus present */ ++#define CC_CAP_EXTBUS_FULL 0x00000040 /* ExtBus: PCMCIA, IDE & Prog */ ++#define CC_CAP_EXTBUS_PROG 0x00000080 /* ExtBus: ProgIf only */ ++#define CC_CAP_FLASH_MASK 0x00000700 /* Type of flash */ ++#define CC_CAP_PLL_MASK 0x00038000 /* Type of PLL */ ++#define CC_CAP_PWR_CTL 0x00040000 /* Power control */ ++#define CC_CAP_OTPSIZE 0x00380000 /* OTP Size (0 = none) */ ++#define CC_CAP_OTPSIZE_SHIFT 19 /* OTP Size shift */ ++#define CC_CAP_OTPSIZE_BASE 5 /* OTP Size base */ ++#define CC_CAP_JTAGP 0x00400000 /* JTAG Master Present */ ++#define CC_CAP_ROM 0x00800000 /* Internal boot rom active */ ++#define CC_CAP_BKPLN64 0x08000000 /* 64-bit backplane */ ++#define CC_CAP_PMU 0x10000000 /* PMU Present, rev >= 20 */ ++#define CC_CAP_ECI 0x20000000 /* ECI Present, rev >= 21 */ ++#define CC_CAP_SROM 0x40000000 /* Srom Present, rev >= 32 */ ++#define CC_CAP_NFLASH 0x80000000 /* Nand flash present, rev >= 35 */ ++ ++#define CC_CAP2_SECI 0x00000001 /* SECI Present, rev >= 36 */ ++#define CC_CAP2_GSIO 0x00000002 /* GSIO (spi/i2c) present, rev >= 37 */ ++ ++/* capabilities extension */ ++#define CC_CAP_EXT_SECI_PRESENT 0x00000001 /* SECI present */ ++ ++/* PLL type */ ++#define PLL_NONE 0x00000000 ++#define PLL_TYPE1 0x00010000 /* 48MHz base, 3 dividers */ ++#define PLL_TYPE2 0x00020000 /* 48MHz, 4 dividers */ ++#define PLL_TYPE3 0x00030000 /* 25MHz, 2 dividers */ ++#define PLL_TYPE4 0x00008000 /* 48MHz, 4 dividers */ ++#define PLL_TYPE5 0x00018000 /* 25MHz, 4 dividers */ ++#define PLL_TYPE6 0x00028000 /* 100/200 or 120/240 only */ ++#define PLL_TYPE7 0x00038000 /* 25MHz, 4 dividers */ ++ ++/* ILP clock */ ++#define ILP_CLOCK 32000 ++ ++/* ALP clock on pre-PMU chips */ ++#define ALP_CLOCK 20000000 ++#define NS_ALP_CLOCK 125000000 ++#define NS_SLOW_ALP_CLOCK 100000000 ++#define NS_CPU_CLOCK 1000000000 ++#define NS_SLOW_CPU_CLOCK 800000000 ++#define NS_SI_CLOCK 250000000 ++#define NS_SLOW_SI_CLOCK 200000000 ++#define NS_FAST_MEM_CLOCK 800000000 ++#define NS_MEM_CLOCK 533000000 ++#define NS_SLOW_MEM_CLOCK 400000000 ++ ++/* HT clock */ ++#define HT_CLOCK 80000000 ++ ++/* corecontrol */ ++#define CC_UARTCLKO 0x00000001 /* Drive UART with internal clock */ ++#define CC_SE 0x00000002 /* sync clk out enable (corerev >= 3) */ ++#define CC_ASYNCGPIO 0x00000004 /* 1=generate GPIO interrupt without backplane clock */ ++#define CC_UARTCLKEN 0x00000008 /* enable UART Clock (corerev > = 21 */ ++ ++/* 4321 chipcontrol */ ++#define CHIPCTRL_4321A0_DEFAULT 0x3a4 ++#define CHIPCTRL_4321A1_DEFAULT 0x0a4 ++#define CHIPCTRL_4321_PLL_DOWN 0x800000 /* serdes PLL down override */ ++ ++/* Fields in the otpstatus register in rev >= 21 */ ++#define OTPS_OL_MASK 0x000000ff ++#define OTPS_OL_MFG 0x00000001 /* manuf row is locked */ ++#define OTPS_OL_OR1 0x00000002 /* otp redundancy row 1 is locked */ ++#define OTPS_OL_OR2 0x00000004 /* otp redundancy row 2 is locked */ ++#define OTPS_OL_GU 0x00000008 /* general use region is locked */ ++#define OTPS_GUP_MASK 0x00000f00 ++#define OTPS_GUP_SHIFT 8 ++#define OTPS_GUP_HW 0x00000100 /* h/w subregion is programmed */ ++#define OTPS_GUP_SW 0x00000200 /* s/w subregion is programmed */ ++#define OTPS_GUP_CI 0x00000400 /* chipid/pkgopt subregion is programmed */ ++#define OTPS_GUP_FUSE 0x00000800 /* fuse subregion is programmed */ ++#define OTPS_READY 0x00001000 ++#define OTPS_RV(x) (1 << (16 + (x))) /* redundancy entry valid */ ++#define OTPS_RV_MASK 0x0fff0000 ++#define OTPS_PROGOK 0x40000000 ++ ++/* Fields in the otpcontrol register in rev >= 21 */ ++#define OTPC_PROGSEL 0x00000001 ++#define OTPC_PCOUNT_MASK 0x0000000e ++#define OTPC_PCOUNT_SHIFT 1 ++#define OTPC_VSEL_MASK 0x000000f0 ++#define OTPC_VSEL_SHIFT 4 ++#define OTPC_TMM_MASK 0x00000700 ++#define OTPC_TMM_SHIFT 8 ++#define OTPC_ODM 0x00000800 ++#define OTPC_PROGEN 0x80000000 ++ ++/* Fields in the 40nm otpcontrol register in rev >= 40 */ ++#define OTPC_40NM_PROGSEL_SHIFT 0 ++#define OTPC_40NM_PCOUNT_SHIFT 1 ++#define OTPC_40NM_PCOUNT_WR 0xA ++#define OTPC_40NM_PCOUNT_V1X 0xB ++#define OTPC_40NM_REGCSEL_SHIFT 5 ++#define OTPC_40NM_REGCSEL_DEF 0x4 ++#define OTPC_40NM_PROGIN_SHIFT 8 ++#define OTPC_40NM_R2X_SHIFT 10 ++#define OTPC_40NM_ODM_SHIFT 11 ++#define OTPC_40NM_DF_SHIFT 15 ++#define OTPC_40NM_VSEL_SHIFT 16 ++#define OTPC_40NM_VSEL_WR 0xA ++#define OTPC_40NM_VSEL_V1X 0xA ++#define OTPC_40NM_VSEL_R1X 0x5 ++#define OTPC_40NM_COFAIL_SHIFT 30 ++ ++#define OTPC1_CPCSEL_SHIFT 0 ++#define OTPC1_CPCSEL_DEF 6 ++#define OTPC1_TM_SHIFT 8 ++#define OTPC1_TM_WR 0x84 ++#define OTPC1_TM_V1X 0x84 ++#define OTPC1_TM_R1X 0x4 ++ ++/* Fields in otpprog in rev >= 21 and HND OTP */ ++#define OTPP_COL_MASK 0x000000ff ++#define OTPP_COL_SHIFT 0 ++#define OTPP_ROW_MASK 0x0000ff00 ++#define OTPP_ROW_SHIFT 8 ++#define OTPP_OC_MASK 0x0f000000 ++#define OTPP_OC_SHIFT 24 ++#define OTPP_READERR 0x10000000 ++#define OTPP_VALUE_MASK 0x20000000 ++#define OTPP_VALUE_SHIFT 29 ++#define OTPP_START_BUSY 0x80000000 ++#define OTPP_READ 0x40000000 /* HND OTP */ ++ ++/* Fields in otplayout register */ ++#define OTPL_HWRGN_OFF_MASK 0x00000FFF ++#define OTPL_HWRGN_OFF_SHIFT 0 ++#define OTPL_WRAP_REVID_MASK 0x00F80000 ++#define OTPL_WRAP_REVID_SHIFT 19 ++#define OTPL_WRAP_TYPE_MASK 0x00070000 ++#define OTPL_WRAP_TYPE_SHIFT 16 ++#define OTPL_WRAP_TYPE_65NM 0 ++#define OTPL_WRAP_TYPE_40NM 1 ++ ++/* otplayout reg corerev >= 36 */ ++#define OTP_CISFORMAT_NEW 0x80000000 ++ ++/* Opcodes for OTPP_OC field */ ++#define OTPPOC_READ 0 ++#define OTPPOC_BIT_PROG 1 ++#define OTPPOC_VERIFY 3 ++#define OTPPOC_INIT 4 ++#define OTPPOC_SET 5 ++#define OTPPOC_RESET 6 ++#define OTPPOC_OCST 7 ++#define OTPPOC_ROW_LOCK 8 ++#define OTPPOC_PRESCN_TEST 9 ++ ++/* Opcodes for OTPP_OC field (40NM) */ ++#define OTPPOC_READ_40NM 0 ++#define OTPPOC_PROG_ENABLE_40NM 1 ++#define OTPPOC_PROG_DISABLE_40NM 2 ++#define OTPPOC_VERIFY_40NM 3 ++#define OTPPOC_WORD_VERIFY_1_40NM 4 ++#define OTPPOC_ROW_LOCK_40NM 5 ++#define OTPPOC_STBY_40NM 6 ++#define OTPPOC_WAKEUP_40NM 7 ++#define OTPPOC_WORD_VERIFY_0_40NM 8 ++#define OTPPOC_PRESCN_TEST_40NM 9 ++#define OTPPOC_BIT_PROG_40NM 10 ++#define OTPPOC_WORDPROG_40NM 11 ++#define OTPPOC_BURNIN_40NM 12 ++#define OTPPOC_AUTORELOAD_40NM 13 ++#define OTPPOC_OVST_READ_40NM 14 ++#define OTPPOC_OVST_PROG_40NM 15 ++ ++/* Fields in otplayoutextension */ ++#define OTPLAYOUTEXT_FUSE_MASK 0x3FF ++ ++ ++/* Jtagm characteristics that appeared at a given corerev */ ++#define JTAGM_CREV_OLD 10 /* Old command set, 16bit max IR */ ++#define JTAGM_CREV_IRP 22 /* Able to do pause-ir */ ++#define JTAGM_CREV_RTI 28 /* Able to do return-to-idle */ ++ ++/* jtagcmd */ ++#define JCMD_START 0x80000000 ++#define JCMD_BUSY 0x80000000 ++#define JCMD_STATE_MASK 0x60000000 ++#define JCMD_STATE_TLR 0x00000000 /* Test-logic-reset */ ++#define JCMD_STATE_PIR 0x20000000 /* Pause IR */ ++#define JCMD_STATE_PDR 0x40000000 /* Pause DR */ ++#define JCMD_STATE_RTI 0x60000000 /* Run-test-idle */ ++#define JCMD0_ACC_MASK 0x0000f000 ++#define JCMD0_ACC_IRDR 0x00000000 ++#define JCMD0_ACC_DR 0x00001000 ++#define JCMD0_ACC_IR 0x00002000 ++#define JCMD0_ACC_RESET 0x00003000 ++#define JCMD0_ACC_IRPDR 0x00004000 ++#define JCMD0_ACC_PDR 0x00005000 ++#define JCMD0_IRW_MASK 0x00000f00 ++#define JCMD_ACC_MASK 0x000f0000 /* Changes for corerev 11 */ ++#define JCMD_ACC_IRDR 0x00000000 ++#define JCMD_ACC_DR 0x00010000 ++#define JCMD_ACC_IR 0x00020000 ++#define JCMD_ACC_RESET 0x00030000 ++#define JCMD_ACC_IRPDR 0x00040000 ++#define JCMD_ACC_PDR 0x00050000 ++#define JCMD_ACC_PIR 0x00060000 ++#define JCMD_ACC_IRDR_I 0x00070000 /* rev 28: return to run-test-idle */ ++#define JCMD_ACC_DR_I 0x00080000 /* rev 28: return to run-test-idle */ ++#define JCMD_IRW_MASK 0x00001f00 ++#define JCMD_IRW_SHIFT 8 ++#define JCMD_DRW_MASK 0x0000003f ++ ++/* jtagctrl */ ++#define JCTRL_FORCE_CLK 4 /* Force clock */ ++#define JCTRL_EXT_EN 2 /* Enable external targets */ ++#define JCTRL_EN 1 /* Enable Jtag master */ ++ ++/* Fields in clkdiv */ ++#define CLKD_SFLASH 0x0f000000 ++#define CLKD_SFLASH_SHIFT 24 ++#define CLKD_OTP 0x000f0000 ++#define CLKD_OTP_SHIFT 16 ++#define CLKD_JTAG 0x00000f00 ++#define CLKD_JTAG_SHIFT 8 ++#define CLKD_UART 0x000000ff ++ ++#define CLKD2_SROM 0x00000003 ++ ++/* intstatus/intmask */ ++#define CI_GPIO 0x00000001 /* gpio intr */ ++#define CI_EI 0x00000002 /* extif intr (corerev >= 3) */ ++#define CI_TEMP 0x00000004 /* temp. ctrl intr (corerev >= 15) */ ++#define CI_SIRQ 0x00000008 /* serial IRQ intr (corerev >= 15) */ ++#define CI_ECI 0x00000010 /* eci intr (corerev >= 21) */ ++#define CI_PMU 0x00000020 /* pmu intr (corerev >= 21) */ ++#define CI_UART 0x00000040 /* uart intr (corerev >= 21) */ ++#define CI_WDRESET 0x80000000 /* watchdog reset occurred */ ++ ++/* slow_clk_ctl */ ++#define SCC_SS_MASK 0x00000007 /* slow clock source mask */ ++#define SCC_SS_LPO 0x00000000 /* source of slow clock is LPO */ ++#define SCC_SS_XTAL 0x00000001 /* source of slow clock is crystal */ ++#define SCC_SS_PCI 0x00000002 /* source of slow clock is PCI */ ++#define SCC_LF 0x00000200 /* LPOFreqSel, 1: 160Khz, 0: 32KHz */ ++#define SCC_LP 0x00000400 /* LPOPowerDown, 1: LPO is disabled, ++ * 0: LPO is enabled ++ */ ++#define SCC_FS 0x00000800 /* ForceSlowClk, 1: sb/cores running on slow clock, ++ * 0: power logic control ++ */ ++#define SCC_IP 0x00001000 /* IgnorePllOffReq, 1/0: power logic ignores/honors ++ * PLL clock disable requests from core ++ */ ++#define SCC_XC 0x00002000 /* XtalControlEn, 1/0: power logic does/doesn't ++ * disable crystal when appropriate ++ */ ++#define SCC_XP 0x00004000 /* XtalPU (RO), 1/0: crystal running/disabled */ ++#define SCC_CD_MASK 0xffff0000 /* ClockDivider (SlowClk = 1/(4+divisor)) */ ++#define SCC_CD_SHIFT 16 ++ ++/* system_clk_ctl */ ++#define SYCC_IE 0x00000001 /* ILPen: Enable Idle Low Power */ ++#define SYCC_AE 0x00000002 /* ALPen: Enable Active Low Power */ ++#define SYCC_FP 0x00000004 /* ForcePLLOn */ ++#define SYCC_AR 0x00000008 /* Force ALP (or HT if ALPen is not set */ ++#define SYCC_HR 0x00000010 /* Force HT */ ++#define SYCC_CD_MASK 0xffff0000 /* ClkDiv (ILP = 1/(4 * (divisor + 1)) */ ++#define SYCC_CD_SHIFT 16 ++ ++/* Indirect backplane access */ ++#define BPIA_BYTEEN 0x0000000f ++#define BPIA_SZ1 0x00000001 ++#define BPIA_SZ2 0x00000003 ++#define BPIA_SZ4 0x00000007 ++#define BPIA_SZ8 0x0000000f ++#define BPIA_WRITE 0x00000100 ++#define BPIA_START 0x00000200 ++#define BPIA_BUSY 0x00000200 ++#define BPIA_ERROR 0x00000400 ++ ++/* pcmcia/prog/flash_config */ ++#define CF_EN 0x00000001 /* enable */ ++#define CF_EM_MASK 0x0000000e /* mode */ ++#define CF_EM_SHIFT 1 ++#define CF_EM_FLASH 0 /* flash/asynchronous mode */ ++#define CF_EM_SYNC 2 /* synchronous mode */ ++#define CF_EM_PCMCIA 4 /* pcmcia mode */ ++#define CF_DS 0x00000010 /* destsize: 0=8bit, 1=16bit */ ++#define CF_BS 0x00000020 /* byteswap */ ++#define CF_CD_MASK 0x000000c0 /* clock divider */ ++#define CF_CD_SHIFT 6 ++#define CF_CD_DIV2 0x00000000 /* backplane/2 */ ++#define CF_CD_DIV3 0x00000040 /* backplane/3 */ ++#define CF_CD_DIV4 0x00000080 /* backplane/4 */ ++#define CF_CE 0x00000100 /* clock enable */ ++#define CF_SB 0x00000200 /* size/bytestrobe (synch only) */ ++ ++/* pcmcia_memwait */ ++#define PM_W0_MASK 0x0000003f /* waitcount0 */ ++#define PM_W1_MASK 0x00001f00 /* waitcount1 */ ++#define PM_W1_SHIFT 8 ++#define PM_W2_MASK 0x001f0000 /* waitcount2 */ ++#define PM_W2_SHIFT 16 ++#define PM_W3_MASK 0x1f000000 /* waitcount3 */ ++#define PM_W3_SHIFT 24 ++ ++/* pcmcia_attrwait */ ++#define PA_W0_MASK 0x0000003f /* waitcount0 */ ++#define PA_W1_MASK 0x00001f00 /* waitcount1 */ ++#define PA_W1_SHIFT 8 ++#define PA_W2_MASK 0x001f0000 /* waitcount2 */ ++#define PA_W2_SHIFT 16 ++#define PA_W3_MASK 0x1f000000 /* waitcount3 */ ++#define PA_W3_SHIFT 24 ++ ++/* pcmcia_iowait */ ++#define PI_W0_MASK 0x0000003f /* waitcount0 */ ++#define PI_W1_MASK 0x00001f00 /* waitcount1 */ ++#define PI_W1_SHIFT 8 ++#define PI_W2_MASK 0x001f0000 /* waitcount2 */ ++#define PI_W2_SHIFT 16 ++#define PI_W3_MASK 0x1f000000 /* waitcount3 */ ++#define PI_W3_SHIFT 24 ++ ++/* prog_waitcount */ ++#define PW_W0_MASK 0x0000001f /* waitcount0 */ ++#define PW_W1_MASK 0x00001f00 /* waitcount1 */ ++#define PW_W1_SHIFT 8 ++#define PW_W2_MASK 0x001f0000 /* waitcount2 */ ++#define PW_W2_SHIFT 16 ++#define PW_W3_MASK 0x1f000000 /* waitcount3 */ ++#define PW_W3_SHIFT 24 ++ ++#define PW_W0 0x0000000c ++#define PW_W1 0x00000a00 ++#define PW_W2 0x00020000 ++#define PW_W3 0x01000000 ++ ++/* flash_waitcount */ ++#define FW_W0_MASK 0x0000003f /* waitcount0 */ ++#define FW_W1_MASK 0x00001f00 /* waitcount1 */ ++#define FW_W1_SHIFT 8 ++#define FW_W2_MASK 0x001f0000 /* waitcount2 */ ++#define FW_W2_SHIFT 16 ++#define FW_W3_MASK 0x1f000000 /* waitcount3 */ ++#define FW_W3_SHIFT 24 ++ ++/* When Srom support present, fields in sromcontrol */ ++#define SRC_START 0x80000000 ++#define SRC_BUSY 0x80000000 ++#define SRC_OPCODE 0x60000000 ++#define SRC_OP_READ 0x00000000 ++#define SRC_OP_WRITE 0x20000000 ++#define SRC_OP_WRDIS 0x40000000 ++#define SRC_OP_WREN 0x60000000 ++#define SRC_OTPSEL 0x00000010 ++#define SRC_LOCK 0x00000008 ++#define SRC_SIZE_MASK 0x00000006 ++#define SRC_SIZE_1K 0x00000000 ++#define SRC_SIZE_4K 0x00000002 ++#define SRC_SIZE_16K 0x00000004 ++#define SRC_SIZE_SHIFT 1 ++#define SRC_PRESENT 0x00000001 ++ ++/* Fields in pmucontrol */ ++#define PCTL_ILP_DIV_MASK 0xffff0000 ++#define PCTL_ILP_DIV_SHIFT 16 ++#define PCTL_PLL_PLLCTL_UPD 0x00000400 /* rev 2 */ ++#define PCTL_NOILP_ON_WAIT 0x00000200 /* rev 1 */ ++#define PCTL_HT_REQ_EN 0x00000100 ++#define PCTL_ALP_REQ_EN 0x00000080 ++#define PCTL_XTALFREQ_MASK 0x0000007c ++#define PCTL_XTALFREQ_SHIFT 2 ++#define PCTL_ILP_DIV_EN 0x00000002 ++#define PCTL_LPO_SEL 0x00000001 ++ ++/* Fields in clkstretch */ ++#define CSTRETCH_HT 0xffff0000 ++#define CSTRETCH_ALP 0x0000ffff ++ ++/* gpiotimerval */ ++#define GPIO_ONTIME_SHIFT 16 ++ ++/* clockcontrol_n */ ++#define CN_N1_MASK 0x3f /* n1 control */ ++#define CN_N2_MASK 0x3f00 /* n2 control */ ++#define CN_N2_SHIFT 8 ++#define CN_PLLC_MASK 0xf0000 /* pll control */ ++#define CN_PLLC_SHIFT 16 ++ ++/* clockcontrol_sb/pci/uart */ ++#define CC_M1_MASK 0x3f /* m1 control */ ++#define CC_M2_MASK 0x3f00 /* m2 control */ ++#define CC_M2_SHIFT 8 ++#define CC_M3_MASK 0x3f0000 /* m3 control */ ++#define CC_M3_SHIFT 16 ++#define CC_MC_MASK 0x1f000000 /* mux control */ ++#define CC_MC_SHIFT 24 ++ ++/* N3M Clock control magic field values */ ++#define CC_F6_2 0x02 /* A factor of 2 in */ ++#define CC_F6_3 0x03 /* 6-bit fields like */ ++#define CC_F6_4 0x05 /* N1, M1 or M3 */ ++#define CC_F6_5 0x09 ++#define CC_F6_6 0x11 ++#define CC_F6_7 0x21 ++ ++#define CC_F5_BIAS 5 /* 5-bit fields get this added */ ++ ++#define CC_MC_BYPASS 0x08 ++#define CC_MC_M1 0x04 ++#define CC_MC_M1M2 0x02 ++#define CC_MC_M1M2M3 0x01 ++#define CC_MC_M1M3 0x11 ++ ++/* Type 2 Clock control magic field values */ ++#define CC_T2_BIAS 2 /* n1, n2, m1 & m3 bias */ ++#define CC_T2M2_BIAS 3 /* m2 bias */ ++ ++#define CC_T2MC_M1BYP 1 ++#define CC_T2MC_M2BYP 2 ++#define CC_T2MC_M3BYP 4 ++ ++/* Type 6 Clock control magic field values */ ++#define CC_T6_MMASK 1 /* bits of interest in m */ ++#define CC_T6_M0 120000000 /* sb clock for m = 0 */ ++#define CC_T6_M1 100000000 /* sb clock for m = 1 */ ++#define SB2MIPS_T6(sb) (2 * (sb)) ++ ++/* Common clock base */ ++#define CC_CLOCK_BASE1 24000000 /* Half the clock freq */ ++#define CC_CLOCK_BASE2 12500000 /* Alternate crystal on some PLLs */ ++ ++/* Clock control values for 200MHz in 5350 */ ++#define CLKC_5350_N 0x0311 ++#define CLKC_5350_M 0x04020009 ++ ++/* Flash types in the chipcommon capabilities register */ ++#define FLASH_NONE 0x000 /* No flash */ ++#define SFLASH_ST 0x100 /* ST serial flash */ ++#define SFLASH_AT 0x200 /* Atmel serial flash */ ++#define NFLASH 0x300 ++#define PFLASH 0x700 /* Parallel flash */ ++#define QSPIFLASH_ST 0x800 ++#define QSPIFLASH_AT 0x900 ++ ++/* Bits in the ExtBus config registers */ ++#define CC_CFG_EN 0x0001 /* Enable */ ++#define CC_CFG_EM_MASK 0x000e /* Extif Mode */ ++#define CC_CFG_EM_ASYNC 0x0000 /* Async/Parallel flash */ ++#define CC_CFG_EM_SYNC 0x0002 /* Synchronous */ ++#define CC_CFG_EM_PCMCIA 0x0004 /* PCMCIA */ ++#define CC_CFG_EM_IDE 0x0006 /* IDE */ ++#define CC_CFG_DS 0x0010 /* Data size, 0=8bit, 1=16bit */ ++#define CC_CFG_CD_MASK 0x00e0 /* Sync: Clock divisor, rev >= 20 */ ++#define CC_CFG_CE 0x0100 /* Sync: Clock enable, rev >= 20 */ ++#define CC_CFG_SB 0x0200 /* Sync: Size/Bytestrobe, rev >= 20 */ ++#define CC_CFG_IS 0x0400 /* Extif Sync Clk Select, rev >= 20 */ ++ ++/* ExtBus address space */ ++#define CC_EB_BASE 0x1a000000 /* Chipc ExtBus base address */ ++#define CC_EB_PCMCIA_MEM 0x1a000000 /* PCMCIA 0 memory base address */ ++#define CC_EB_PCMCIA_IO 0x1a200000 /* PCMCIA 0 I/O base address */ ++#define CC_EB_PCMCIA_CFG 0x1a400000 /* PCMCIA 0 config base address */ ++#define CC_EB_IDE 0x1a800000 /* IDE memory base */ ++#define CC_EB_PCMCIA1_MEM 0x1a800000 /* PCMCIA 1 memory base address */ ++#define CC_EB_PCMCIA1_IO 0x1aa00000 /* PCMCIA 1 I/O base address */ ++#define CC_EB_PCMCIA1_CFG 0x1ac00000 /* PCMCIA 1 config base address */ ++#define CC_EB_PROGIF 0x1b000000 /* ProgIF Async/Sync base address */ ++ ++ ++/* Start/busy bit in flashcontrol */ ++#define SFLASH_OPCODE 0x000000ff ++#define SFLASH_ACTION 0x00000700 ++#define SFLASH_CS_ACTIVE 0x00001000 /* Chip Select Active, rev >= 20 */ ++#define SFLASH_START 0x80000000 ++#define SFLASH_BUSY SFLASH_START ++ ++/* flashcontrol action codes */ ++#define SFLASH_ACT_OPONLY 0x0000 /* Issue opcode only */ ++#define SFLASH_ACT_OP1D 0x0100 /* opcode + 1 data byte */ ++#define SFLASH_ACT_OP3A 0x0200 /* opcode + 3 addr bytes */ ++#define SFLASH_ACT_OP3A1D 0x0300 /* opcode + 3 addr & 1 data bytes */ ++#define SFLASH_ACT_OP3A4D 0x0400 /* opcode + 3 addr & 4 data bytes */ ++#define SFLASH_ACT_OP3A4X4D 0x0500 /* opcode + 3 addr, 4 don't care & 4 data bytes */ ++#define SFLASH_ACT_OP3A1X4D 0x0700 /* opcode + 3 addr, 1 don't care & 4 data bytes */ ++ ++/* flashcontrol action+opcodes for ST flashes */ ++#define SFLASH_ST_WREN 0x0006 /* Write Enable */ ++#define SFLASH_ST_WRDIS 0x0004 /* Write Disable */ ++#define SFLASH_ST_RDSR 0x0105 /* Read Status Register */ ++#define SFLASH_ST_WRSR 0x0101 /* Write Status Register */ ++#define SFLASH_ST_READ 0x0303 /* Read Data Bytes */ ++#define SFLASH_ST_PP 0x0302 /* Page Program */ ++#define SFLASH_ST_SE 0x02d8 /* Sector Erase */ ++#define SFLASH_ST_BE 0x00c7 /* Bulk Erase */ ++#define SFLASH_ST_DP 0x00b9 /* Deep Power-down */ ++#define SFLASH_ST_RES 0x03ab /* Read Electronic Signature */ ++#define SFLASH_ST_CSA 0x1000 /* Keep chip select asserted */ ++#define SFLASH_ST_SSE 0x0220 /* Sub-sector Erase */ ++ ++#define SFLASH_MXIC_RDID 0x0390 /* Read Manufacture ID */ ++#define SFLASH_MXIC_MFID 0xc2 /* MXIC Manufacture ID */ ++ ++/* Status register bits for ST flashes */ ++#define SFLASH_ST_WIP 0x01 /* Write In Progress */ ++#define SFLASH_ST_WEL 0x02 /* Write Enable Latch */ ++#define SFLASH_ST_BP_MASK 0x1c /* Block Protect */ ++#define SFLASH_ST_BP_SHIFT 2 ++#define SFLASH_ST_SRWD 0x80 /* Status Register Write Disable */ ++ ++/* flashcontrol action+opcodes for Atmel flashes */ ++#define SFLASH_AT_READ 0x07e8 ++#define SFLASH_AT_PAGE_READ 0x07d2 ++#define SFLASH_AT_BUF1_READ ++#define SFLASH_AT_BUF2_READ ++#define SFLASH_AT_STATUS 0x01d7 ++#define SFLASH_AT_BUF1_WRITE 0x0384 ++#define SFLASH_AT_BUF2_WRITE 0x0387 ++#define SFLASH_AT_BUF1_ERASE_PROGRAM 0x0283 ++#define SFLASH_AT_BUF2_ERASE_PROGRAM 0x0286 ++#define SFLASH_AT_BUF1_PROGRAM 0x0288 ++#define SFLASH_AT_BUF2_PROGRAM 0x0289 ++#define SFLASH_AT_PAGE_ERASE 0x0281 ++#define SFLASH_AT_BLOCK_ERASE 0x0250 ++#define SFLASH_AT_BUF1_WRITE_ERASE_PROGRAM 0x0382 ++#define SFLASH_AT_BUF2_WRITE_ERASE_PROGRAM 0x0385 ++#define SFLASH_AT_BUF1_LOAD 0x0253 ++#define SFLASH_AT_BUF2_LOAD 0x0255 ++#define SFLASH_AT_BUF1_COMPARE 0x0260 ++#define SFLASH_AT_BUF2_COMPARE 0x0261 ++#define SFLASH_AT_BUF1_REPROGRAM 0x0258 ++#define SFLASH_AT_BUF2_REPROGRAM 0x0259 ++ ++/* Status register bits for Atmel flashes */ ++#define SFLASH_AT_READY 0x80 ++#define SFLASH_AT_MISMATCH 0x40 ++#define SFLASH_AT_ID_MASK 0x38 ++#define SFLASH_AT_ID_SHIFT 3 ++ ++/* SPI register bits, corerev >= 37 */ ++#define GSIO_START 0x80000000 ++#define GSIO_BUSY GSIO_START ++ ++/* ++ * These are the UART port assignments, expressed as offsets from the base ++ * register. These assignments should hold for any serial port based on ++ * a 8250, 16450, or 16550(A). ++ */ ++ ++#define UART_RX 0 /* In: Receive buffer (DLAB=0) */ ++#define UART_TX 0 /* Out: Transmit buffer (DLAB=0) */ ++#define UART_DLL 0 /* Out: Divisor Latch Low (DLAB=1) */ ++#define UART_IER 1 /* In/Out: Interrupt Enable Register (DLAB=0) */ ++#define UART_DLM 1 /* Out: Divisor Latch High (DLAB=1) */ ++#define UART_IIR 2 /* In: Interrupt Identity Register */ ++#define UART_FCR 2 /* Out: FIFO Control Register */ ++#define UART_LCR 3 /* Out: Line Control Register */ ++#define UART_MCR 4 /* Out: Modem Control Register */ ++#define UART_LSR 5 /* In: Line Status Register */ ++#define UART_MSR 6 /* In: Modem Status Register */ ++#define UART_SCR 7 /* I/O: Scratch Register */ ++#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */ ++#define UART_LCR_WLEN8 0x03 /* Word length: 8 bits */ ++#define UART_MCR_OUT2 0x08 /* MCR GPIO out 2 */ ++#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */ ++#define UART_LSR_RX_FIFO 0x80 /* Receive FIFO error */ ++#define UART_LSR_TDHR 0x40 /* Data-hold-register empty */ ++#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */ ++#define UART_LSR_BREAK 0x10 /* Break interrupt */ ++#define UART_LSR_FRAMING 0x08 /* Framing error */ ++#define UART_LSR_PARITY 0x04 /* Parity error */ ++#define UART_LSR_OVERRUN 0x02 /* Overrun error */ ++#define UART_LSR_RXRDY 0x01 /* Receiver ready */ ++#define UART_FCR_FIFO_ENABLE 1 /* FIFO control register bit controlling FIFO enable/disable */ ++ ++/* Interrupt Identity Register (IIR) bits */ ++#define UART_IIR_FIFO_MASK 0xc0 /* IIR FIFO disable/enabled mask */ ++#define UART_IIR_INT_MASK 0xf /* IIR interrupt ID source */ ++#define UART_IIR_MDM_CHG 0x0 /* Modem status changed */ ++#define UART_IIR_NOINT 0x1 /* No interrupt pending */ ++#define UART_IIR_THRE 0x2 /* THR empty */ ++#define UART_IIR_RCVD_DATA 0x4 /* Received data available */ ++#define UART_IIR_RCVR_STATUS 0x6 /* Receiver status */ ++#define UART_IIR_CHAR_TIME 0xc /* Character time */ ++ ++/* Interrupt Enable Register (IER) bits */ ++#define UART_IER_EDSSI 8 /* enable modem status interrupt */ ++#define UART_IER_ELSI 4 /* enable receiver line status interrupt */ ++#define UART_IER_ETBEI 2 /* enable transmitter holding register empty interrupt */ ++#define UART_IER_ERBFI 1 /* enable data available interrupt */ ++ ++/* pmustatus */ ++#define PST_EXTLPOAVAIL 0x0100 ++#define PST_WDRESET 0x0080 ++#define PST_INTPEND 0x0040 ++#define PST_SBCLKST 0x0030 ++#define PST_SBCLKST_ILP 0x0010 ++#define PST_SBCLKST_ALP 0x0020 ++#define PST_SBCLKST_HT 0x0030 ++#define PST_ALPAVAIL 0x0008 ++#define PST_HTAVAIL 0x0004 ++#define PST_RESINIT 0x0003 ++ ++/* pmucapabilities */ ++#define PCAP_REV_MASK 0x000000ff ++#define PCAP_RC_MASK 0x00001f00 ++#define PCAP_RC_SHIFT 8 ++#define PCAP_TC_MASK 0x0001e000 ++#define PCAP_TC_SHIFT 13 ++#define PCAP_PC_MASK 0x001e0000 ++#define PCAP_PC_SHIFT 17 ++#define PCAP_VC_MASK 0x01e00000 ++#define PCAP_VC_SHIFT 21 ++#define PCAP_CC_MASK 0x1e000000 ++#define PCAP_CC_SHIFT 25 ++#define PCAP5_PC_MASK 0x003e0000 /* PMU corerev >= 5 */ ++#define PCAP5_PC_SHIFT 17 ++#define PCAP5_VC_MASK 0x07c00000 ++#define PCAP5_VC_SHIFT 22 ++#define PCAP5_CC_MASK 0xf8000000 ++#define PCAP5_CC_SHIFT 27 ++ ++/* PMU Resource Request Timer registers */ ++/* This is based on PmuRev0 */ ++#define PRRT_TIME_MASK 0x03ff ++#define PRRT_INTEN 0x0400 ++#define PRRT_REQ_ACTIVE 0x0800 ++#define PRRT_ALP_REQ 0x1000 ++#define PRRT_HT_REQ 0x2000 ++#define PRRT_HQ_REQ 0x4000 ++ ++/* PMU resource bit position */ ++#define PMURES_BIT(bit) (1 << (bit)) ++ ++/* PMU resource number limit */ ++#define PMURES_MAX_RESNUM 30 ++ ++/* PMU chip control0 register */ ++#define PMU_CHIPCTL0 0 ++ ++/* clock req types */ ++#define PMU_CC1_CLKREQ_TYPE_SHIFT 19 ++#define PMU_CC1_CLKREQ_TYPE_MASK (1 << PMU_CC1_CLKREQ_TYPE_SHIFT) ++ ++#define CLKREQ_TYPE_CONFIG_OPENDRAIN 0 ++#define CLKREQ_TYPE_CONFIG_PUSHPULL 1 ++ ++/* PMU chip control1 register */ ++#define PMU_CHIPCTL1 1 ++#define PMU_CC1_RXC_DLL_BYPASS 0x00010000 ++ ++#define PMU_CC1_IF_TYPE_MASK 0x00000030 ++#define PMU_CC1_IF_TYPE_RMII 0x00000000 ++#define PMU_CC1_IF_TYPE_MII 0x00000010 ++#define PMU_CC1_IF_TYPE_RGMII 0x00000020 ++ ++#define PMU_CC1_SW_TYPE_MASK 0x000000c0 ++#define PMU_CC1_SW_TYPE_EPHY 0x00000000 ++#define PMU_CC1_SW_TYPE_EPHYMII 0x00000040 ++#define PMU_CC1_SW_TYPE_EPHYRMII 0x00000080 ++#define PMU_CC1_SW_TYPE_RGMII 0x000000c0 ++ ++/* PMU chip control2 register */ ++#define PMU_CHIPCTL2 2 ++ ++/* PMU chip control3 register */ ++#define PMU_CHIPCTL3 3 ++ ++#define PMU_CC3_ENABLE_SDIO_WAKEUP_SHIFT 19 ++#define PMU_CC3_ENABLE_RF_SHIFT 22 ++#define PMU_CC3_RF_DISABLE_IVALUE_SHIFT 23 ++ ++ ++/* PMU corerev and chip specific PLL controls. ++ * PMU_PLL_XX where is PMU corerev and is an arbitrary number ++ * to differentiate different PLLs controlled by the same PMU rev. ++ */ ++/* pllcontrol registers */ ++/* PDIV, div_phy, div_arm, div_adc, dith_sel, ioff, kpd_scale, lsb_sel, mash_sel, lf_c & lf_r */ ++#define PMU0_PLL0_PLLCTL0 0 ++#define PMU0_PLL0_PC0_PDIV_MASK 1 ++#define PMU0_PLL0_PC0_PDIV_FREQ 25000 ++#define PMU0_PLL0_PC0_DIV_ARM_MASK 0x00000038 ++#define PMU0_PLL0_PC0_DIV_ARM_SHIFT 3 ++#define PMU0_PLL0_PC0_DIV_ARM_BASE 8 ++ ++/* PC0_DIV_ARM for PLLOUT_ARM */ ++#define PMU0_PLL0_PC0_DIV_ARM_110MHZ 0 ++#define PMU0_PLL0_PC0_DIV_ARM_97_7MHZ 1 ++#define PMU0_PLL0_PC0_DIV_ARM_88MHZ 2 ++#define PMU0_PLL0_PC0_DIV_ARM_80MHZ 3 /* Default */ ++#define PMU0_PLL0_PC0_DIV_ARM_73_3MHZ 4 ++#define PMU0_PLL0_PC0_DIV_ARM_67_7MHZ 5 ++#define PMU0_PLL0_PC0_DIV_ARM_62_9MHZ 6 ++#define PMU0_PLL0_PC0_DIV_ARM_58_6MHZ 7 ++ ++/* Wildcard base, stop_mod, en_lf_tp, en_cal & lf_r2 */ ++#define PMU0_PLL0_PLLCTL1 1 ++#define PMU0_PLL0_PC1_WILD_INT_MASK 0xf0000000 ++#define PMU0_PLL0_PC1_WILD_INT_SHIFT 28 ++#define PMU0_PLL0_PC1_WILD_FRAC_MASK 0x0fffff00 ++#define PMU0_PLL0_PC1_WILD_FRAC_SHIFT 8 ++#define PMU0_PLL0_PC1_STOP_MOD 0x00000040 ++ ++/* Wildcard base, vco_calvar, vco_swc, vco_var_selref, vso_ical & vco_sel_avdd */ ++#define PMU0_PLL0_PLLCTL2 2 ++#define PMU0_PLL0_PC2_WILD_INT_MASK 0xf ++#define PMU0_PLL0_PC2_WILD_INT_SHIFT 4 ++ ++/* pllcontrol registers */ ++/* ndiv_pwrdn, pwrdn_ch, refcomp_pwrdn, dly_ch, p1div, p2div, _bypass_sdmod */ ++#define PMU1_PLL0_PLLCTL0 0 ++#define PMU1_PLL0_PC0_P1DIV_MASK 0x00f00000 ++#define PMU1_PLL0_PC0_P1DIV_SHIFT 20 ++#define PMU1_PLL0_PC0_P2DIV_MASK 0x0f000000 ++#define PMU1_PLL0_PC0_P2DIV_SHIFT 24 ++ ++/* mdiv */ ++#define PMU1_PLL0_PLLCTL1 1 ++#define PMU1_PLL0_PC1_M1DIV_MASK 0x000000ff ++#define PMU1_PLL0_PC1_M1DIV_SHIFT 0 ++#define PMU1_PLL0_PC1_M2DIV_MASK 0x0000ff00 ++#define PMU1_PLL0_PC1_M2DIV_SHIFT 8 ++#define PMU1_PLL0_PC1_M3DIV_MASK 0x00ff0000 ++#define PMU1_PLL0_PC1_M3DIV_SHIFT 16 ++#define PMU1_PLL0_PC1_M4DIV_MASK 0xff000000 ++#define PMU1_PLL0_PC1_M4DIV_SHIFT 24 ++#define PMU1_PLL0_PC1_M4DIV_BY_9 9 ++#define PMU1_PLL0_PC1_M4DIV_BY_18 0x12 ++#define PMU1_PLL0_PC1_M4DIV_BY_36 0x24 ++ ++#define DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT 8 ++#define DOT11MAC_880MHZ_CLK_DIVISOR_MASK (0xFF << DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT) ++#define DOT11MAC_880MHZ_CLK_DIVISOR_VAL (0xE << DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT) ++ ++/* mdiv, ndiv_dither_mfb, ndiv_mode, ndiv_int */ ++#define PMU1_PLL0_PLLCTL2 2 ++#define PMU1_PLL0_PC2_M5DIV_MASK 0x000000ff ++#define PMU1_PLL0_PC2_M5DIV_SHIFT 0 ++#define PMU1_PLL0_PC2_M5DIV_BY_12 0xc ++#define PMU1_PLL0_PC2_M5DIV_BY_18 0x12 ++#define PMU1_PLL0_PC2_M5DIV_BY_36 0x24 ++#define PMU1_PLL0_PC2_M6DIV_MASK 0x0000ff00 ++#define PMU1_PLL0_PC2_M6DIV_SHIFT 8 ++#define PMU1_PLL0_PC2_M6DIV_BY_18 0x12 ++#define PMU1_PLL0_PC2_M6DIV_BY_36 0x24 ++#define PMU1_PLL0_PC2_NDIV_MODE_MASK 0x000e0000 ++#define PMU1_PLL0_PC2_NDIV_MODE_SHIFT 17 ++#define PMU1_PLL0_PC2_NDIV_MODE_MASH 1 ++#define PMU1_PLL0_PC2_NDIV_MODE_MFB 2 /* recommended for 4319 */ ++#define PMU1_PLL0_PC2_NDIV_INT_MASK 0x1ff00000 ++#define PMU1_PLL0_PC2_NDIV_INT_SHIFT 20 ++ ++/* ndiv_frac */ ++#define PMU1_PLL0_PLLCTL3 3 ++#define PMU1_PLL0_PC3_NDIV_FRAC_MASK 0x00ffffff ++#define PMU1_PLL0_PC3_NDIV_FRAC_SHIFT 0 ++ ++/* pll_ctrl */ ++#define PMU1_PLL0_PLLCTL4 4 ++ ++/* pll_ctrl, vco_rng, clkdrive_ch */ ++#define PMU1_PLL0_PLLCTL5 5 ++#define PMU1_PLL0_PC5_CLK_DRV_MASK 0xffffff00 ++#define PMU1_PLL0_PC5_CLK_DRV_SHIFT 8 ++ ++/* PMU rev 2 control words */ ++#define PMU2_PHY_PLL_PLLCTL 4 ++#define PMU2_SI_PLL_PLLCTL 10 ++ ++/* PMU rev 2 */ ++/* pllcontrol registers */ ++/* ndiv_pwrdn, pwrdn_ch, refcomp_pwrdn, dly_ch, p1div, p2div, _bypass_sdmod */ ++#define PMU2_PLL_PLLCTL0 0 ++#define PMU2_PLL_PC0_P1DIV_MASK 0x00f00000 ++#define PMU2_PLL_PC0_P1DIV_SHIFT 20 ++#define PMU2_PLL_PC0_P2DIV_MASK 0x0f000000 ++#define PMU2_PLL_PC0_P2DIV_SHIFT 24 ++ ++/* mdiv */ ++#define PMU2_PLL_PLLCTL1 1 ++#define PMU2_PLL_PC1_M1DIV_MASK 0x000000ff ++#define PMU2_PLL_PC1_M1DIV_SHIFT 0 ++#define PMU2_PLL_PC1_M2DIV_MASK 0x0000ff00 ++#define PMU2_PLL_PC1_M2DIV_SHIFT 8 ++#define PMU2_PLL_PC1_M3DIV_MASK 0x00ff0000 ++#define PMU2_PLL_PC1_M3DIV_SHIFT 16 ++#define PMU2_PLL_PC1_M4DIV_MASK 0xff000000 ++#define PMU2_PLL_PC1_M4DIV_SHIFT 24 ++ ++/* mdiv, ndiv_dither_mfb, ndiv_mode, ndiv_int */ ++#define PMU2_PLL_PLLCTL2 2 ++#define PMU2_PLL_PC2_M5DIV_MASK 0x000000ff ++#define PMU2_PLL_PC2_M5DIV_SHIFT 0 ++#define PMU2_PLL_PC2_M6DIV_MASK 0x0000ff00 ++#define PMU2_PLL_PC2_M6DIV_SHIFT 8 ++#define PMU2_PLL_PC2_NDIV_MODE_MASK 0x000e0000 ++#define PMU2_PLL_PC2_NDIV_MODE_SHIFT 17 ++#define PMU2_PLL_PC2_NDIV_INT_MASK 0x1ff00000 ++#define PMU2_PLL_PC2_NDIV_INT_SHIFT 20 ++ ++/* ndiv_frac */ ++#define PMU2_PLL_PLLCTL3 3 ++#define PMU2_PLL_PC3_NDIV_FRAC_MASK 0x00ffffff ++#define PMU2_PLL_PC3_NDIV_FRAC_SHIFT 0 ++ ++/* pll_ctrl */ ++#define PMU2_PLL_PLLCTL4 4 ++ ++/* pll_ctrl, vco_rng, clkdrive_ch */ ++#define PMU2_PLL_PLLCTL5 5 ++#define PMU2_PLL_PC5_CLKDRIVE_CH1_MASK 0x00000f00 ++#define PMU2_PLL_PC5_CLKDRIVE_CH1_SHIFT 8 ++#define PMU2_PLL_PC5_CLKDRIVE_CH2_MASK 0x0000f000 ++#define PMU2_PLL_PC5_CLKDRIVE_CH2_SHIFT 12 ++#define PMU2_PLL_PC5_CLKDRIVE_CH3_MASK 0x000f0000 ++#define PMU2_PLL_PC5_CLKDRIVE_CH3_SHIFT 16 ++#define PMU2_PLL_PC5_CLKDRIVE_CH4_MASK 0x00f00000 ++#define PMU2_PLL_PC5_CLKDRIVE_CH4_SHIFT 20 ++#define PMU2_PLL_PC5_CLKDRIVE_CH5_MASK 0x0f000000 ++#define PMU2_PLL_PC5_CLKDRIVE_CH5_SHIFT 24 ++#define PMU2_PLL_PC5_CLKDRIVE_CH6_MASK 0xf0000000 ++#define PMU2_PLL_PC5_CLKDRIVE_CH6_SHIFT 28 ++ ++/* PMU rev 5 (& 6) */ ++#define PMU5_PLL_P1P2_OFF 0 ++#define PMU5_PLL_P1_MASK 0x0f000000 ++#define PMU5_PLL_P1_SHIFT 24 ++#define PMU5_PLL_P2_MASK 0x00f00000 ++#define PMU5_PLL_P2_SHIFT 20 ++#define PMU5_PLL_M14_OFF 1 ++#define PMU5_PLL_MDIV_MASK 0x000000ff ++#define PMU5_PLL_MDIV_WIDTH 8 ++#define PMU5_PLL_NM5_OFF 2 ++#define PMU5_PLL_NDIV_MASK 0xfff00000 ++#define PMU5_PLL_NDIV_SHIFT 20 ++#define PMU5_PLL_NDIV_MODE_MASK 0x000e0000 ++#define PMU5_PLL_NDIV_MODE_SHIFT 17 ++#define PMU5_PLL_FMAB_OFF 3 ++#define PMU5_PLL_MRAT_MASK 0xf0000000 ++#define PMU5_PLL_MRAT_SHIFT 28 ++#define PMU5_PLL_ABRAT_MASK 0x08000000 ++#define PMU5_PLL_ABRAT_SHIFT 27 ++#define PMU5_PLL_FDIV_MASK 0x07ffffff ++#define PMU5_PLL_PLLCTL_OFF 4 ++#define PMU5_PLL_PCHI_OFF 5 ++#define PMU5_PLL_PCHI_MASK 0x0000003f ++ ++/* pmu XtalFreqRatio */ ++#define PMU_XTALFREQ_REG_ILPCTR_MASK 0x00001FFF ++#define PMU_XTALFREQ_REG_MEASURE_MASK 0x80000000 ++#define PMU_XTALFREQ_REG_MEASURE_SHIFT 31 ++ ++/* Divider allocation in 4716/47162/5356/5357 */ ++#define PMU5_MAINPLL_CPU 1 ++#define PMU5_MAINPLL_MEM 2 ++#define PMU5_MAINPLL_SI 3 ++ ++/* 4706 PMU */ ++#define PMU4706_MAINPLL_PLL0 0 ++#define PMU6_4706_PROCPLL_OFF 4 /* The CPU PLL */ ++#define PMU6_4706_PROC_P2DIV_MASK 0x000f0000 ++#define PMU6_4706_PROC_P2DIV_SHIFT 16 ++#define PMU6_4706_PROC_P1DIV_MASK 0x0000f000 ++#define PMU6_4706_PROC_P1DIV_SHIFT 12 ++#define PMU6_4706_PROC_NDIV_INT_MASK 0x00000ff8 ++#define PMU6_4706_PROC_NDIV_INT_SHIFT 3 ++#define PMU6_4706_PROC_NDIV_MODE_MASK 0x00000007 ++#define PMU6_4706_PROC_NDIV_MODE_SHIFT 0 ++ ++#define PMU7_PLL_PLLCTL7 7 ++#define PMU7_PLL_CTL7_M4DIV_MASK 0xff000000 ++#define PMU7_PLL_CTL7_M4DIV_SHIFT 24 ++#define PMU7_PLL_CTL7_M4DIV_BY_6 6 ++#define PMU7_PLL_CTL7_M4DIV_BY_12 0xc ++#define PMU7_PLL_CTL7_M4DIV_BY_24 0x18 ++#define PMU7_PLL_PLLCTL8 8 ++#define PMU7_PLL_CTL8_M5DIV_MASK 0x000000ff ++#define PMU7_PLL_CTL8_M5DIV_SHIFT 0 ++#define PMU7_PLL_CTL8_M5DIV_BY_8 8 ++#define PMU7_PLL_CTL8_M5DIV_BY_12 0xc ++#define PMU7_PLL_CTL8_M5DIV_BY_24 0x18 ++#define PMU7_PLL_CTL8_M6DIV_MASK 0x0000ff00 ++#define PMU7_PLL_CTL8_M6DIV_SHIFT 8 ++#define PMU7_PLL_CTL8_M6DIV_BY_12 0xc ++#define PMU7_PLL_CTL8_M6DIV_BY_24 0x18 ++#define PMU7_PLL_PLLCTL11 11 ++#define PMU7_PLL_PLLCTL11_MASK 0xffffff00 ++#define PMU7_PLL_PLLCTL11_VAL 0x22222200 ++ ++/* PMU rev 15 */ ++#define PMU15_PLL_PLLCTL0 0 ++#define PMU15_PLL_PC0_CLKSEL_MASK 0x00000003 ++#define PMU15_PLL_PC0_CLKSEL_SHIFT 0 ++#define PMU15_PLL_PC0_FREQTGT_MASK 0x003FFFFC ++#define PMU15_PLL_PC0_FREQTGT_SHIFT 2 ++#define PMU15_PLL_PC0_PRESCALE_MASK 0x00C00000 ++#define PMU15_PLL_PC0_PRESCALE_SHIFT 22 ++#define PMU15_PLL_PC0_KPCTRL_MASK 0x07000000 ++#define PMU15_PLL_PC0_KPCTRL_SHIFT 24 ++#define PMU15_PLL_PC0_FCNTCTRL_MASK 0x38000000 ++#define PMU15_PLL_PC0_FCNTCTRL_SHIFT 27 ++#define PMU15_PLL_PC0_FDCMODE_MASK 0x40000000 ++#define PMU15_PLL_PC0_FDCMODE_SHIFT 30 ++#define PMU15_PLL_PC0_CTRLBIAS_MASK 0x80000000 ++#define PMU15_PLL_PC0_CTRLBIAS_SHIFT 31 ++ ++#define PMU15_PLL_PLLCTL1 1 ++#define PMU15_PLL_PC1_BIAS_CTLM_MASK 0x00000060 ++#define PMU15_PLL_PC1_BIAS_CTLM_SHIFT 5 ++#define PMU15_PLL_PC1_BIAS_CTLM_RST_MASK 0x00000040 ++#define PMU15_PLL_PC1_BIAS_CTLM_RST_SHIFT 6 ++#define PMU15_PLL_PC1_BIAS_SS_DIVR_MASK 0x0001FF80 ++#define PMU15_PLL_PC1_BIAS_SS_DIVR_SHIFT 7 ++#define PMU15_PLL_PC1_BIAS_SS_RSTVAL_MASK 0x03FE0000 ++#define PMU15_PLL_PC1_BIAS_SS_RSTVAL_SHIFT 17 ++#define PMU15_PLL_PC1_BIAS_INTG_BW_MASK 0x0C000000 ++#define PMU15_PLL_PC1_BIAS_INTG_BW_SHIFT 26 ++#define PMU15_PLL_PC1_BIAS_INTG_BYP_MASK 0x10000000 ++#define PMU15_PLL_PC1_BIAS_INTG_BYP_SHIFT 28 ++#define PMU15_PLL_PC1_OPENLP_EN_MASK 0x40000000 ++#define PMU15_PLL_PC1_OPENLP_EN_SHIFT 30 ++ ++#define PMU15_PLL_PLLCTL2 2 ++#define PMU15_PLL_PC2_CTEN_MASK 0x00000001 ++#define PMU15_PLL_PC2_CTEN_SHIFT 0 ++ ++#define PMU15_PLL_PLLCTL3 3 ++#define PMU15_PLL_PC3_DITHER_EN_MASK 0x00000001 ++#define PMU15_PLL_PC3_DITHER_EN_SHIFT 0 ++#define PMU15_PLL_PC3_DCOCTLSP_MASK 0xFE000000 ++#define PMU15_PLL_PC3_DCOCTLSP_SHIFT 25 ++#define PMU15_PLL_PC3_DCOCTLSP_DIV2EN_MASK 0x01 ++#define PMU15_PLL_PC3_DCOCTLSP_DIV2EN_SHIFT 0 ++#define PMU15_PLL_PC3_DCOCTLSP_CH0EN_MASK 0x02 ++#define PMU15_PLL_PC3_DCOCTLSP_CH0EN_SHIFT 1 ++#define PMU15_PLL_PC3_DCOCTLSP_CH1EN_MASK 0x04 ++#define PMU15_PLL_PC3_DCOCTLSP_CH1EN_SHIFT 2 ++#define PMU15_PLL_PC3_DCOCTLSP_CH0SEL_MASK 0x18 ++#define PMU15_PLL_PC3_DCOCTLSP_CH0SEL_SHIFT 3 ++#define PMU15_PLL_PC3_DCOCTLSP_CH1SEL_MASK 0x60 ++#define PMU15_PLL_PC3_DCOCTLSP_CH1SEL_SHIFT 5 ++#define PMU15_PLL_PC3_DCOCTLSP_CHSEL_OUTP_DIV1 0 ++#define PMU15_PLL_PC3_DCOCTLSP_CHSEL_OUTP_DIV2 1 ++#define PMU15_PLL_PC3_DCOCTLSP_CHSEL_OUTP_DIV3 2 ++#define PMU15_PLL_PC3_DCOCTLSP_CHSEL_OUTP_DIV5 3 ++ ++#define PMU15_PLL_PLLCTL4 4 ++#define PMU15_PLL_PC4_FLLCLK1_DIV_MASK 0x00000007 ++#define PMU15_PLL_PC4_FLLCLK1_DIV_SHIFT 0 ++#define PMU15_PLL_PC4_FLLCLK2_DIV_MASK 0x00000038 ++#define PMU15_PLL_PC4_FLLCLK2_DIV_SHIFT 3 ++#define PMU15_PLL_PC4_FLLCLK3_DIV_MASK 0x000001C0 ++#define PMU15_PLL_PC4_FLLCLK3_DIV_SHIFT 6 ++#define PMU15_PLL_PC4_DBGMODE_MASK 0x00000E00 ++#define PMU15_PLL_PC4_DBGMODE_SHIFT 9 ++#define PMU15_PLL_PC4_FLL480_CTLSP_LK_MASK 0x00001000 ++#define PMU15_PLL_PC4_FLL480_CTLSP_LK_SHIFT 12 ++#define PMU15_PLL_PC4_FLL480_CTLSP_MASK 0x000FE000 ++#define PMU15_PLL_PC4_FLL480_CTLSP_SHIFT 13 ++#define PMU15_PLL_PC4_DINPOL_MASK 0x00100000 ++#define PMU15_PLL_PC4_DINPOL_SHIFT 20 ++#define PMU15_PLL_PC4_CLKOUT_PD_MASK 0x00200000 ++#define PMU15_PLL_PC4_CLKOUT_PD_SHIFT 21 ++#define PMU15_PLL_PC4_CLKDIV2_PD_MASK 0x00400000 ++#define PMU15_PLL_PC4_CLKDIV2_PD_SHIFT 22 ++#define PMU15_PLL_PC4_CLKDIV4_PD_MASK 0x00800000 ++#define PMU15_PLL_PC4_CLKDIV4_PD_SHIFT 23 ++#define PMU15_PLL_PC4_CLKDIV8_PD_MASK 0x01000000 ++#define PMU15_PLL_PC4_CLKDIV8_PD_SHIFT 24 ++#define PMU15_PLL_PC4_CLKDIV16_PD_MASK 0x02000000 ++#define PMU15_PLL_PC4_CLKDIV16_PD_SHIFT 25 ++#define PMU15_PLL_PC4_TEST_EN_MASK 0x04000000 ++#define PMU15_PLL_PC4_TEST_EN_SHIFT 26 ++ ++#define PMU15_PLL_PLLCTL5 5 ++#define PMU15_PLL_PC5_FREQTGT_MASK 0x000FFFFF ++#define PMU15_PLL_PC5_FREQTGT_SHIFT 0 ++#define PMU15_PLL_PC5_DCOCTLSP_MASK 0x07F00000 ++#define PMU15_PLL_PC5_DCOCTLSP_SHIFT 20 ++#define PMU15_PLL_PC5_PRESCALE_MASK 0x18000000 ++#define PMU15_PLL_PC5_PRESCALE_SHIFT 27 ++ ++#define PMU15_PLL_PLLCTL6 6 ++#define PMU15_PLL_PC6_FREQTGT_MASK 0x000FFFFF ++#define PMU15_PLL_PC6_FREQTGT_SHIFT 0 ++#define PMU15_PLL_PC6_DCOCTLSP_MASK 0x07F00000 ++#define PMU15_PLL_PC6_DCOCTLSP_SHIFT 20 ++#define PMU15_PLL_PC6_PRESCALE_MASK 0x18000000 ++#define PMU15_PLL_PC6_PRESCALE_SHIFT 27 ++ ++#define PMU15_FREQTGT_480_DEFAULT 0x19AB1 ++#define PMU15_FREQTGT_492_DEFAULT 0x1A4F5 ++#define PMU15_ARM_96MHZ 96000000 /* 96 Mhz */ ++#define PMU15_ARM_98MHZ 98400000 /* 98.4 Mhz */ ++#define PMU15_ARM_97MHZ 97000000 /* 97 Mhz */ ++ ++ ++#define PMU17_PLLCTL2_NDIVTYPE_MASK 0x00000070 ++#define PMU17_PLLCTL2_NDIVTYPE_SHIFT 4 ++ ++#define PMU17_PLLCTL2_NDIV_MODE_INT 0 ++#define PMU17_PLLCTL2_NDIV_MODE_INT1B8 1 ++#define PMU17_PLLCTL2_NDIV_MODE_MASH111 2 ++#define PMU17_PLLCTL2_NDIV_MODE_MASH111B8 3 ++ ++#define PMU17_PLLCTL0_BBPLL_PWRDWN 0 ++#define PMU17_PLLCTL0_BBPLL_DRST 3 ++#define PMU17_PLLCTL0_BBPLL_DISBL_CLK 8 ++ ++/* PLL usage in 4716/47162 */ ++#define PMU4716_MAINPLL_PLL0 12 ++ ++/* PLL usage in 5356/5357 */ ++#define PMU5356_MAINPLL_PLL0 0 ++#define PMU5357_MAINPLL_PLL0 0 ++ ++/* 4716/47162 resources */ ++#define RES4716_PROC_PLL_ON 0x00000040 ++#define RES4716_PROC_HT_AVAIL 0x00000080 ++ ++/* 4716/4717/4718 Chip specific ChipControl register bits */ ++#define CCTRL_471X_I2S_PINS_ENABLE 0x0080 /* I2S pins off by default, shared w/ pflash */ ++ ++/* 5357 Chip specific ChipControl register bits */ ++/* 2nd - 32-bit reg */ ++#define CCTRL_5357_I2S_PINS_ENABLE 0x00040000 /* I2S pins enable */ ++#define CCTRL_5357_I2CSPI_PINS_ENABLE 0x00080000 /* I2C/SPI pins enable */ ++ ++/* 5354 resources */ ++#define RES5354_EXT_SWITCHER_PWM 0 /* 0x00001 */ ++#define RES5354_BB_SWITCHER_PWM 1 /* 0x00002 */ ++#define RES5354_BB_SWITCHER_BURST 2 /* 0x00004 */ ++#define RES5354_BB_EXT_SWITCHER_BURST 3 /* 0x00008 */ ++#define RES5354_ILP_REQUEST 4 /* 0x00010 */ ++#define RES5354_RADIO_SWITCHER_PWM 5 /* 0x00020 */ ++#define RES5354_RADIO_SWITCHER_BURST 6 /* 0x00040 */ ++#define RES5354_ROM_SWITCH 7 /* 0x00080 */ ++#define RES5354_PA_REF_LDO 8 /* 0x00100 */ ++#define RES5354_RADIO_LDO 9 /* 0x00200 */ ++#define RES5354_AFE_LDO 10 /* 0x00400 */ ++#define RES5354_PLL_LDO 11 /* 0x00800 */ ++#define RES5354_BG_FILTBYP 12 /* 0x01000 */ ++#define RES5354_TX_FILTBYP 13 /* 0x02000 */ ++#define RES5354_RX_FILTBYP 14 /* 0x04000 */ ++#define RES5354_XTAL_PU 15 /* 0x08000 */ ++#define RES5354_XTAL_EN 16 /* 0x10000 */ ++#define RES5354_BB_PLL_FILTBYP 17 /* 0x20000 */ ++#define RES5354_RF_PLL_FILTBYP 18 /* 0x40000 */ ++#define RES5354_BB_PLL_PU 19 /* 0x80000 */ ++ ++/* 5357 Chip specific ChipControl register bits */ ++#define CCTRL5357_EXTPA (1<<14) /* extPA in ChipControl 1, bit 14 */ ++#define CCTRL5357_ANT_MUX_2o3 (1<<15) /* 2o3 in ChipControl 1, bit 15 */ ++#define CCTRL5357_NFLASH (1<<16) /* Nandflash in ChipControl 1, bit 16 */ ++ ++/* 4328 resources */ ++#define RES4328_EXT_SWITCHER_PWM 0 /* 0x00001 */ ++#define RES4328_BB_SWITCHER_PWM 1 /* 0x00002 */ ++#define RES4328_BB_SWITCHER_BURST 2 /* 0x00004 */ ++#define RES4328_BB_EXT_SWITCHER_BURST 3 /* 0x00008 */ ++#define RES4328_ILP_REQUEST 4 /* 0x00010 */ ++#define RES4328_RADIO_SWITCHER_PWM 5 /* 0x00020 */ ++#define RES4328_RADIO_SWITCHER_BURST 6 /* 0x00040 */ ++#define RES4328_ROM_SWITCH 7 /* 0x00080 */ ++#define RES4328_PA_REF_LDO 8 /* 0x00100 */ ++#define RES4328_RADIO_LDO 9 /* 0x00200 */ ++#define RES4328_AFE_LDO 10 /* 0x00400 */ ++#define RES4328_PLL_LDO 11 /* 0x00800 */ ++#define RES4328_BG_FILTBYP 12 /* 0x01000 */ ++#define RES4328_TX_FILTBYP 13 /* 0x02000 */ ++#define RES4328_RX_FILTBYP 14 /* 0x04000 */ ++#define RES4328_XTAL_PU 15 /* 0x08000 */ ++#define RES4328_XTAL_EN 16 /* 0x10000 */ ++#define RES4328_BB_PLL_FILTBYP 17 /* 0x20000 */ ++#define RES4328_RF_PLL_FILTBYP 18 /* 0x40000 */ ++#define RES4328_BB_PLL_PU 19 /* 0x80000 */ ++ ++/* 4325 A0/A1 resources */ ++#define RES4325_BUCK_BOOST_BURST 0 /* 0x00000001 */ ++#define RES4325_CBUCK_BURST 1 /* 0x00000002 */ ++#define RES4325_CBUCK_PWM 2 /* 0x00000004 */ ++#define RES4325_CLDO_CBUCK_BURST 3 /* 0x00000008 */ ++#define RES4325_CLDO_CBUCK_PWM 4 /* 0x00000010 */ ++#define RES4325_BUCK_BOOST_PWM 5 /* 0x00000020 */ ++#define RES4325_ILP_REQUEST 6 /* 0x00000040 */ ++#define RES4325_ABUCK_BURST 7 /* 0x00000080 */ ++#define RES4325_ABUCK_PWM 8 /* 0x00000100 */ ++#define RES4325_LNLDO1_PU 9 /* 0x00000200 */ ++#define RES4325_OTP_PU 10 /* 0x00000400 */ ++#define RES4325_LNLDO3_PU 11 /* 0x00000800 */ ++#define RES4325_LNLDO4_PU 12 /* 0x00001000 */ ++#define RES4325_XTAL_PU 13 /* 0x00002000 */ ++#define RES4325_ALP_AVAIL 14 /* 0x00004000 */ ++#define RES4325_RX_PWRSW_PU 15 /* 0x00008000 */ ++#define RES4325_TX_PWRSW_PU 16 /* 0x00010000 */ ++#define RES4325_RFPLL_PWRSW_PU 17 /* 0x00020000 */ ++#define RES4325_LOGEN_PWRSW_PU 18 /* 0x00040000 */ ++#define RES4325_AFE_PWRSW_PU 19 /* 0x00080000 */ ++#define RES4325_BBPLL_PWRSW_PU 20 /* 0x00100000 */ ++#define RES4325_HT_AVAIL 21 /* 0x00200000 */ ++ ++/* 4325 B0/C0 resources */ ++#define RES4325B0_CBUCK_LPOM 1 /* 0x00000002 */ ++#define RES4325B0_CBUCK_BURST 2 /* 0x00000004 */ ++#define RES4325B0_CBUCK_PWM 3 /* 0x00000008 */ ++#define RES4325B0_CLDO_PU 4 /* 0x00000010 */ ++ ++/* 4325 C1 resources */ ++#define RES4325C1_LNLDO2_PU 12 /* 0x00001000 */ ++ ++/* 4325 chip-specific ChipStatus register bits */ ++#define CST4325_SPROM_OTP_SEL_MASK 0x00000003 ++#define CST4325_DEFCIS_SEL 0 /* OTP is powered up, use def. CIS, no SPROM */ ++#define CST4325_SPROM_SEL 1 /* OTP is powered up, SPROM is present */ ++#define CST4325_OTP_SEL 2 /* OTP is powered up, no SPROM */ ++#define CST4325_OTP_PWRDN 3 /* OTP is powered down, SPROM is present */ ++#define CST4325_SDIO_USB_MODE_MASK 0x00000004 ++#define CST4325_SDIO_USB_MODE_SHIFT 2 ++#define CST4325_RCAL_VALID_MASK 0x00000008 ++#define CST4325_RCAL_VALID_SHIFT 3 ++#define CST4325_RCAL_VALUE_MASK 0x000001f0 ++#define CST4325_RCAL_VALUE_SHIFT 4 ++#define CST4325_PMUTOP_2B_MASK 0x00000200 /* 1 for 2b, 0 for to 2a */ ++#define CST4325_PMUTOP_2B_SHIFT 9 ++ ++#define RES4329_RESERVED0 0 /* 0x00000001 */ ++#define RES4329_CBUCK_LPOM 1 /* 0x00000002 */ ++#define RES4329_CBUCK_BURST 2 /* 0x00000004 */ ++#define RES4329_CBUCK_PWM 3 /* 0x00000008 */ ++#define RES4329_CLDO_PU 4 /* 0x00000010 */ ++#define RES4329_PALDO_PU 5 /* 0x00000020 */ ++#define RES4329_ILP_REQUEST 6 /* 0x00000040 */ ++#define RES4329_RESERVED7 7 /* 0x00000080 */ ++#define RES4329_RESERVED8 8 /* 0x00000100 */ ++#define RES4329_LNLDO1_PU 9 /* 0x00000200 */ ++#define RES4329_OTP_PU 10 /* 0x00000400 */ ++#define RES4329_RESERVED11 11 /* 0x00000800 */ ++#define RES4329_LNLDO2_PU 12 /* 0x00001000 */ ++#define RES4329_XTAL_PU 13 /* 0x00002000 */ ++#define RES4329_ALP_AVAIL 14 /* 0x00004000 */ ++#define RES4329_RX_PWRSW_PU 15 /* 0x00008000 */ ++#define RES4329_TX_PWRSW_PU 16 /* 0x00010000 */ ++#define RES4329_RFPLL_PWRSW_PU 17 /* 0x00020000 */ ++#define RES4329_LOGEN_PWRSW_PU 18 /* 0x00040000 */ ++#define RES4329_AFE_PWRSW_PU 19 /* 0x00080000 */ ++#define RES4329_BBPLL_PWRSW_PU 20 /* 0x00100000 */ ++#define RES4329_HT_AVAIL 21 /* 0x00200000 */ ++ ++#define CST4329_SPROM_OTP_SEL_MASK 0x00000003 ++#define CST4329_DEFCIS_SEL 0 /* OTP is powered up, use def. CIS, no SPROM */ ++#define CST4329_SPROM_SEL 1 /* OTP is powered up, SPROM is present */ ++#define CST4329_OTP_SEL 2 /* OTP is powered up, no SPROM */ ++#define CST4329_OTP_PWRDN 3 /* OTP is powered down, SPROM is present */ ++#define CST4329_SPI_SDIO_MODE_MASK 0x00000004 ++#define CST4329_SPI_SDIO_MODE_SHIFT 2 ++ ++/* 4312 chip-specific ChipStatus register bits */ ++#define CST4312_SPROM_OTP_SEL_MASK 0x00000003 ++#define CST4312_DEFCIS_SEL 0 /* OTP is powered up, use def. CIS, no SPROM */ ++#define CST4312_SPROM_SEL 1 /* OTP is powered up, SPROM is present */ ++#define CST4312_OTP_SEL 2 /* OTP is powered up, no SPROM */ ++#define CST4312_OTP_BAD 3 /* OTP is broken, SPROM is present */ ++ ++/* 4312 resources (all PMU chips with little memory constraint) */ ++#define RES4312_SWITCHER_BURST 0 /* 0x00000001 */ ++#define RES4312_SWITCHER_PWM 1 /* 0x00000002 */ ++#define RES4312_PA_REF_LDO 2 /* 0x00000004 */ ++#define RES4312_CORE_LDO_BURST 3 /* 0x00000008 */ ++#define RES4312_CORE_LDO_PWM 4 /* 0x00000010 */ ++#define RES4312_RADIO_LDO 5 /* 0x00000020 */ ++#define RES4312_ILP_REQUEST 6 /* 0x00000040 */ ++#define RES4312_BG_FILTBYP 7 /* 0x00000080 */ ++#define RES4312_TX_FILTBYP 8 /* 0x00000100 */ ++#define RES4312_RX_FILTBYP 9 /* 0x00000200 */ ++#define RES4312_XTAL_PU 10 /* 0x00000400 */ ++#define RES4312_ALP_AVAIL 11 /* 0x00000800 */ ++#define RES4312_BB_PLL_FILTBYP 12 /* 0x00001000 */ ++#define RES4312_RF_PLL_FILTBYP 13 /* 0x00002000 */ ++#define RES4312_HT_AVAIL 14 /* 0x00004000 */ ++ ++/* 4322 resources */ ++#define RES4322_RF_LDO 0 ++#define RES4322_ILP_REQUEST 1 ++#define RES4322_XTAL_PU 2 ++#define RES4322_ALP_AVAIL 3 ++#define RES4322_SI_PLL_ON 4 ++#define RES4322_HT_SI_AVAIL 5 ++#define RES4322_PHY_PLL_ON 6 ++#define RES4322_HT_PHY_AVAIL 7 ++#define RES4322_OTP_PU 8 ++ ++/* 4322 chip-specific ChipStatus register bits */ ++#define CST4322_XTAL_FREQ_20_40MHZ 0x00000020 ++#define CST4322_SPROM_OTP_SEL_MASK 0x000000c0 ++#define CST4322_SPROM_OTP_SEL_SHIFT 6 ++#define CST4322_NO_SPROM_OTP 0 /* no OTP, no SPROM */ ++#define CST4322_SPROM_PRESENT 1 /* SPROM is present */ ++#define CST4322_OTP_PRESENT 2 /* OTP is present */ ++#define CST4322_PCI_OR_USB 0x00000100 ++#define CST4322_BOOT_MASK 0x00000600 ++#define CST4322_BOOT_SHIFT 9 ++#define CST4322_BOOT_FROM_SRAM 0 /* boot from SRAM, ARM in reset */ ++#define CST4322_BOOT_FROM_ROM 1 /* boot from ROM */ ++#define CST4322_BOOT_FROM_FLASH 2 /* boot from FLASH */ ++#define CST4322_BOOT_FROM_INVALID 3 ++#define CST4322_ILP_DIV_EN 0x00000800 ++#define CST4322_FLASH_TYPE_MASK 0x00001000 ++#define CST4322_FLASH_TYPE_SHIFT 12 ++#define CST4322_FLASH_TYPE_SHIFT_ST 0 /* ST serial FLASH */ ++#define CST4322_FLASH_TYPE_SHIFT_ATMEL 1 /* ATMEL flash */ ++#define CST4322_ARM_TAP_SEL 0x00002000 ++#define CST4322_RES_INIT_MODE_MASK 0x0000c000 ++#define CST4322_RES_INIT_MODE_SHIFT 14 ++#define CST4322_RES_INIT_MODE_ILPAVAIL 0 /* resinitmode: ILP available */ ++#define CST4322_RES_INIT_MODE_ILPREQ 1 /* resinitmode: ILP request */ ++#define CST4322_RES_INIT_MODE_ALPAVAIL 2 /* resinitmode: ALP available */ ++#define CST4322_RES_INIT_MODE_HTAVAIL 3 /* resinitmode: HT available */ ++#define CST4322_PCIPLLCLK_GATING 0x00010000 ++#define CST4322_CLK_SWITCH_PCI_TO_ALP 0x00020000 ++#define CST4322_PCI_CARDBUS_MODE 0x00040000 ++ ++/* 43224 chip-specific ChipControl register bits */ ++#define CCTRL43224_GPIO_TOGGLE 0x8000 /* gpio[3:0] pins as btcoex or s/w gpio */ ++#define CCTRL_43224A0_12MA_LED_DRIVE 0x00F000F0 /* 12 mA drive strength */ ++#define CCTRL_43224B0_12MA_LED_DRIVE 0xF0 /* 12 mA drive strength for later 43224s */ ++ ++/* 43236 resources */ ++#define RES43236_REGULATOR 0 ++#define RES43236_ILP_REQUEST 1 ++#define RES43236_XTAL_PU 2 ++#define RES43236_ALP_AVAIL 3 ++#define RES43236_SI_PLL_ON 4 ++#define RES43236_HT_SI_AVAIL 5 ++ ++/* 43236 chip-specific ChipControl register bits */ ++#define CCTRL43236_BT_COEXIST (1<<0) /* 0 disable */ ++#define CCTRL43236_SECI (1<<1) /* 0 SECI is disabled (JATG functional) */ ++#define CCTRL43236_EXT_LNA (1<<2) /* 0 disable */ ++#define CCTRL43236_ANT_MUX_2o3 (1<<3) /* 2o3 mux, chipcontrol bit 3 */ ++#define CCTRL43236_GSIO (1<<4) /* 0 disable */ ++ ++/* 43236 Chip specific ChipStatus register bits */ ++#define CST43236_SFLASH_MASK 0x00000040 ++#define CST43236_OTP_SEL_MASK 0x00000080 ++#define CST43236_OTP_SEL_SHIFT 7 ++#define CST43236_HSIC_MASK 0x00000100 /* USB/HSIC */ ++#define CST43236_BP_CLK 0x00000200 /* 120/96Mbps */ ++#define CST43236_BOOT_MASK 0x00001800 ++#define CST43236_BOOT_SHIFT 11 ++#define CST43236_BOOT_FROM_SRAM 0 /* boot from SRAM, ARM in reset */ ++#define CST43236_BOOT_FROM_ROM 1 /* boot from ROM */ ++#define CST43236_BOOT_FROM_FLASH 2 /* boot from FLASH */ ++#define CST43236_BOOT_FROM_INVALID 3 ++ ++/* 43237 resources */ ++#define RES43237_REGULATOR 0 ++#define RES43237_ILP_REQUEST 1 ++#define RES43237_XTAL_PU 2 ++#define RES43237_ALP_AVAIL 3 ++#define RES43237_SI_PLL_ON 4 ++#define RES43237_HT_SI_AVAIL 5 ++ ++/* 43237 chip-specific ChipControl register bits */ ++#define CCTRL43237_BT_COEXIST (1<<0) /* 0 disable */ ++#define CCTRL43237_SECI (1<<1) /* 0 SECI is disabled (JATG functional) */ ++#define CCTRL43237_EXT_LNA (1<<2) /* 0 disable */ ++#define CCTRL43237_ANT_MUX_2o3 (1<<3) /* 2o3 mux, chipcontrol bit 3 */ ++#define CCTRL43237_GSIO (1<<4) /* 0 disable */ ++ ++/* 43237 Chip specific ChipStatus register bits */ ++#define CST43237_SFLASH_MASK 0x00000040 ++#define CST43237_OTP_SEL_MASK 0x00000080 ++#define CST43237_OTP_SEL_SHIFT 7 ++#define CST43237_HSIC_MASK 0x00000100 /* USB/HSIC */ ++#define CST43237_BP_CLK 0x00000200 /* 120/96Mbps */ ++#define CST43237_BOOT_MASK 0x00001800 ++#define CST43237_BOOT_SHIFT 11 ++#define CST43237_BOOT_FROM_SRAM 0 /* boot from SRAM, ARM in reset */ ++#define CST43237_BOOT_FROM_ROM 1 /* boot from ROM */ ++#define CST43237_BOOT_FROM_FLASH 2 /* boot from FLASH */ ++#define CST43237_BOOT_FROM_INVALID 3 ++ ++/* 43239 resources */ ++#define RES43239_OTP_PU 9 ++#define RES43239_MACPHY_CLKAVAIL 23 ++#define RES43239_HT_AVAIL 24 ++ ++/* 43239 Chip specific ChipStatus register bits */ ++#define CST43239_SPROM_MASK 0x00000002 ++#define CST43239_SFLASH_MASK 0x00000004 ++#define CST43239_RES_INIT_MODE_SHIFT 7 ++#define CST43239_RES_INIT_MODE_MASK 0x000001f0 ++#define CST43239_CHIPMODE_SDIOD(cs) ((cs) & (1 << 15)) /* SDIO || gSPI */ ++#define CST43239_CHIPMODE_USB20D(cs) (~(cs) & (1 << 15)) /* USB || USBDA */ ++#define CST43239_CHIPMODE_SDIO(cs) (((cs) & (1 << 0)) == 0) /* SDIO */ ++#define CST43239_CHIPMODE_GSPI(cs) (((cs) & (1 << 0)) == (1 << 0)) /* gSPI */ ++ ++/* 4324 resources */ ++#define RES4324_OTP_PU 10 ++#define RES4324_HT_AVAIL 29 ++#define RES4324_MACPHY_CLKAVAIL 30 ++ ++/* 4324 Chip specific ChipStatus register bits */ ++#define CST4324_SPROM_MASK 0x00000080 ++#define CST4324_SFLASH_MASK 0x00400000 ++#define CST4324_RES_INIT_MODE_SHIFT 10 ++#define CST4324_RES_INIT_MODE_MASK 0x00000c00 ++#define CST4324_CHIPMODE_MASK 0x7 ++#define CST4324_CHIPMODE_SDIOD(cs) ((~(cs)) & (1 << 2)) /* SDIO || gSPI */ ++#define CST4324_CHIPMODE_USB20D(cs) (((cs) & CST4324_CHIPMODE_MASK) == 0x6) /* USB || USBDA */ ++ ++/* 4331 resources */ ++#define RES4331_REGULATOR 0 ++#define RES4331_ILP_REQUEST 1 ++#define RES4331_XTAL_PU 2 ++#define RES4331_ALP_AVAIL 3 ++#define RES4331_SI_PLL_ON 4 ++#define RES4331_HT_SI_AVAIL 5 ++ ++/* 4331 chip-specific ChipControl register bits */ ++#define CCTRL4331_BT_COEXIST (1<<0) /* 0 disable */ ++#define CCTRL4331_SECI (1<<1) /* 0 SECI is disabled (JATG functional) */ ++#define CCTRL4331_EXT_LNA_G (1<<2) /* 0 disable */ ++#define CCTRL4331_SPROM_GPIO13_15 (1<<3) /* sprom/gpio13-15 mux */ ++#define CCTRL4331_EXTPA_EN (1<<4) /* 0 ext pa disable, 1 ext pa enabled */ ++#define CCTRL4331_GPIOCLK_ON_SPROMCS (1<<5) /* set drive out GPIO_CLK on sprom_cs pin */ ++#define CCTRL4331_PCIE_MDIO_ON_SPROMCS (1<<6) /* use sprom_cs pin as PCIE mdio interface */ ++#define CCTRL4331_EXTPA_ON_GPIO2_5 (1<<7) /* aband extpa will be at gpio2/5 and sprom_dout */ ++#define CCTRL4331_OVR_PIPEAUXCLKEN (1<<8) /* override core control on pipe_AuxClkEnable */ ++#define CCTRL4331_OVR_PIPEAUXPWRDOWN (1<<9) /* override core control on pipe_AuxPowerDown */ ++#define CCTRL4331_PCIE_AUXCLKEN (1<<10) /* pcie_auxclkenable */ ++#define CCTRL4331_PCIE_PIPE_PLLDOWN (1<<11) /* pcie_pipe_pllpowerdown */ ++#define CCTRL4331_EXTPA_EN2 (1<<12) /* 0 ext pa disable, 1 ext pa enabled */ ++#define CCTRL4331_EXT_LNA_A (1<<13) /* 0 disable */ ++#define CCTRL4331_BT_SHD0_ON_GPIO4 (1<<16) /* enable bt_shd0 at gpio4 */ ++#define CCTRL4331_BT_SHD1_ON_GPIO5 (1<<17) /* enable bt_shd1 at gpio5 */ ++#define CCTRL4331_EXTPA_ANA_EN (1<<24) /* 0 ext pa disable, 1 ext pa enabled */ ++ ++/* 4331 Chip specific ChipStatus register bits */ ++#define CST4331_XTAL_FREQ 0x00000001 /* crystal frequency 20/40Mhz */ ++#define CST4331_SPROM_OTP_SEL_MASK 0x00000006 ++#define CST4331_SPROM_OTP_SEL_SHIFT 1 ++#define CST4331_SPROM_PRESENT 0x00000002 ++#define CST4331_OTP_PRESENT 0x00000004 ++#define CST4331_LDO_RF 0x00000008 ++#define CST4331_LDO_PAR 0x00000010 ++ ++/* 4315 resource */ ++#define RES4315_CBUCK_LPOM 1 /* 0x00000002 */ ++#define RES4315_CBUCK_BURST 2 /* 0x00000004 */ ++#define RES4315_CBUCK_PWM 3 /* 0x00000008 */ ++#define RES4315_CLDO_PU 4 /* 0x00000010 */ ++#define RES4315_PALDO_PU 5 /* 0x00000020 */ ++#define RES4315_ILP_REQUEST 6 /* 0x00000040 */ ++#define RES4315_LNLDO1_PU 9 /* 0x00000200 */ ++#define RES4315_OTP_PU 10 /* 0x00000400 */ ++#define RES4315_LNLDO2_PU 12 /* 0x00001000 */ ++#define RES4315_XTAL_PU 13 /* 0x00002000 */ ++#define RES4315_ALP_AVAIL 14 /* 0x00004000 */ ++#define RES4315_RX_PWRSW_PU 15 /* 0x00008000 */ ++#define RES4315_TX_PWRSW_PU 16 /* 0x00010000 */ ++#define RES4315_RFPLL_PWRSW_PU 17 /* 0x00020000 */ ++#define RES4315_LOGEN_PWRSW_PU 18 /* 0x00040000 */ ++#define RES4315_AFE_PWRSW_PU 19 /* 0x00080000 */ ++#define RES4315_BBPLL_PWRSW_PU 20 /* 0x00100000 */ ++#define RES4315_HT_AVAIL 21 /* 0x00200000 */ ++ ++/* 4315 chip-specific ChipStatus register bits */ ++#define CST4315_SPROM_OTP_SEL_MASK 0x00000003 /* gpio [7:6], SDIO CIS selection */ ++#define CST4315_DEFCIS_SEL 0x00000000 /* use default CIS, OTP is powered up */ ++#define CST4315_SPROM_SEL 0x00000001 /* use SPROM, OTP is powered up */ ++#define CST4315_OTP_SEL 0x00000002 /* use OTP, OTP is powered up */ ++#define CST4315_OTP_PWRDN 0x00000003 /* use SPROM, OTP is powered down */ ++#define CST4315_SDIO_MODE 0x00000004 /* gpio [8], sdio/usb mode */ ++#define CST4315_RCAL_VALID 0x00000008 ++#define CST4315_RCAL_VALUE_MASK 0x000001f0 ++#define CST4315_RCAL_VALUE_SHIFT 4 ++#define CST4315_PALDO_EXTPNP 0x00000200 /* PALDO is configured with external PNP */ ++#define CST4315_CBUCK_MODE_MASK 0x00000c00 ++#define CST4315_CBUCK_MODE_BURST 0x00000400 ++#define CST4315_CBUCK_MODE_LPBURST 0x00000c00 ++ ++/* 4319 resources */ ++#define RES4319_CBUCK_LPOM 1 /* 0x00000002 */ ++#define RES4319_CBUCK_BURST 2 /* 0x00000004 */ ++#define RES4319_CBUCK_PWM 3 /* 0x00000008 */ ++#define RES4319_CLDO_PU 4 /* 0x00000010 */ ++#define RES4319_PALDO_PU 5 /* 0x00000020 */ ++#define RES4319_ILP_REQUEST 6 /* 0x00000040 */ ++#define RES4319_LNLDO1_PU 9 /* 0x00000200 */ ++#define RES4319_OTP_PU 10 /* 0x00000400 */ ++#define RES4319_LNLDO2_PU 12 /* 0x00001000 */ ++#define RES4319_XTAL_PU 13 /* 0x00002000 */ ++#define RES4319_ALP_AVAIL 14 /* 0x00004000 */ ++#define RES4319_RX_PWRSW_PU 15 /* 0x00008000 */ ++#define RES4319_TX_PWRSW_PU 16 /* 0x00010000 */ ++#define RES4319_RFPLL_PWRSW_PU 17 /* 0x00020000 */ ++#define RES4319_LOGEN_PWRSW_PU 18 /* 0x00040000 */ ++#define RES4319_AFE_PWRSW_PU 19 /* 0x00080000 */ ++#define RES4319_BBPLL_PWRSW_PU 20 /* 0x00100000 */ ++#define RES4319_HT_AVAIL 21 /* 0x00200000 */ ++ ++/* 4319 chip-specific ChipStatus register bits */ ++#define CST4319_SPI_CPULESSUSB 0x00000001 ++#define CST4319_SPI_CLK_POL 0x00000002 ++#define CST4319_SPI_CLK_PH 0x00000008 ++#define CST4319_SPROM_OTP_SEL_MASK 0x000000c0 /* gpio [7:6], SDIO CIS selection */ ++#define CST4319_SPROM_OTP_SEL_SHIFT 6 ++#define CST4319_DEFCIS_SEL 0x00000000 /* use default CIS, OTP is powered up */ ++#define CST4319_SPROM_SEL 0x00000040 /* use SPROM, OTP is powered up */ ++#define CST4319_OTP_SEL 0x00000080 /* use OTP, OTP is powered up */ ++#define CST4319_OTP_PWRDN 0x000000c0 /* use SPROM, OTP is powered down */ ++#define CST4319_SDIO_USB_MODE 0x00000100 /* gpio [8], sdio/usb mode */ ++#define CST4319_REMAP_SEL_MASK 0x00000600 ++#define CST4319_ILPDIV_EN 0x00000800 ++#define CST4319_XTAL_PD_POL 0x00001000 ++#define CST4319_LPO_SEL 0x00002000 ++#define CST4319_RES_INIT_MODE 0x0000c000 ++#define CST4319_PALDO_EXTPNP 0x00010000 /* PALDO is configured with external PNP */ ++#define CST4319_CBUCK_MODE_MASK 0x00060000 ++#define CST4319_CBUCK_MODE_BURST 0x00020000 ++#define CST4319_CBUCK_MODE_LPBURST 0x00060000 ++#define CST4319_RCAL_VALID 0x01000000 ++#define CST4319_RCAL_VALUE_MASK 0x3e000000 ++#define CST4319_RCAL_VALUE_SHIFT 25 ++ ++#define PMU1_PLL0_CHIPCTL0 0 ++#define PMU1_PLL0_CHIPCTL1 1 ++#define PMU1_PLL0_CHIPCTL2 2 ++#define CCTL_4319USB_XTAL_SEL_MASK 0x00180000 ++#define CCTL_4319USB_XTAL_SEL_SHIFT 19 ++#define CCTL_4319USB_48MHZ_PLL_SEL 1 ++#define CCTL_4319USB_24MHZ_PLL_SEL 2 ++ ++/* PMU resources for 4336 */ ++#define RES4336_CBUCK_LPOM 0 ++#define RES4336_CBUCK_BURST 1 ++#define RES4336_CBUCK_LP_PWM 2 ++#define RES4336_CBUCK_PWM 3 ++#define RES4336_CLDO_PU 4 ++#define RES4336_DIS_INT_RESET_PD 5 ++#define RES4336_ILP_REQUEST 6 ++#define RES4336_LNLDO_PU 7 ++#define RES4336_LDO3P3_PU 8 ++#define RES4336_OTP_PU 9 ++#define RES4336_XTAL_PU 10 ++#define RES4336_ALP_AVAIL 11 ++#define RES4336_RADIO_PU 12 ++#define RES4336_BG_PU 13 ++#define RES4336_VREG1p4_PU_PU 14 ++#define RES4336_AFE_PWRSW_PU 15 ++#define RES4336_RX_PWRSW_PU 16 ++#define RES4336_TX_PWRSW_PU 17 ++#define RES4336_BB_PWRSW_PU 18 ++#define RES4336_SYNTH_PWRSW_PU 19 ++#define RES4336_MISC_PWRSW_PU 20 ++#define RES4336_LOGEN_PWRSW_PU 21 ++#define RES4336_BBPLL_PWRSW_PU 22 ++#define RES4336_MACPHY_CLKAVAIL 23 ++#define RES4336_HT_AVAIL 24 ++#define RES4336_RSVD 25 ++ ++/* 4336 chip-specific ChipStatus register bits */ ++#define CST4336_SPI_MODE_MASK 0x00000001 ++#define CST4336_SPROM_PRESENT 0x00000002 ++#define CST4336_OTP_PRESENT 0x00000004 ++#define CST4336_ARMREMAP_0 0x00000008 ++#define CST4336_ILPDIV_EN_MASK 0x00000010 ++#define CST4336_ILPDIV_EN_SHIFT 4 ++#define CST4336_XTAL_PD_POL_MASK 0x00000020 ++#define CST4336_XTAL_PD_POL_SHIFT 5 ++#define CST4336_LPO_SEL_MASK 0x00000040 ++#define CST4336_LPO_SEL_SHIFT 6 ++#define CST4336_RES_INIT_MODE_MASK 0x00000180 ++#define CST4336_RES_INIT_MODE_SHIFT 7 ++#define CST4336_CBUCK_MODE_MASK 0x00000600 ++#define CST4336_CBUCK_MODE_SHIFT 9 ++ ++/* 4336 Chip specific PMU ChipControl register bits */ ++#define PCTL_4336_SERIAL_ENAB (1 << 24) ++ ++/* 4330 resources */ ++#define RES4330_CBUCK_LPOM 0 ++#define RES4330_CBUCK_BURST 1 ++#define RES4330_CBUCK_LP_PWM 2 ++#define RES4330_CBUCK_PWM 3 ++#define RES4330_CLDO_PU 4 ++#define RES4330_DIS_INT_RESET_PD 5 ++#define RES4330_ILP_REQUEST 6 ++#define RES4330_LNLDO_PU 7 ++#define RES4330_LDO3P3_PU 8 ++#define RES4330_OTP_PU 9 ++#define RES4330_XTAL_PU 10 ++#define RES4330_ALP_AVAIL 11 ++#define RES4330_RADIO_PU 12 ++#define RES4330_BG_PU 13 ++#define RES4330_VREG1p4_PU_PU 14 ++#define RES4330_AFE_PWRSW_PU 15 ++#define RES4330_RX_PWRSW_PU 16 ++#define RES4330_TX_PWRSW_PU 17 ++#define RES4330_BB_PWRSW_PU 18 ++#define RES4330_SYNTH_PWRSW_PU 19 ++#define RES4330_MISC_PWRSW_PU 20 ++#define RES4330_LOGEN_PWRSW_PU 21 ++#define RES4330_BBPLL_PWRSW_PU 22 ++#define RES4330_MACPHY_CLKAVAIL 23 ++#define RES4330_HT_AVAIL 24 ++#define RES4330_5gRX_PWRSW_PU 25 ++#define RES4330_5gTX_PWRSW_PU 26 ++#define RES4330_5g_LOGEN_PWRSW_PU 27 ++ ++/* 4330 chip-specific ChipStatus register bits */ ++#define CST4330_CHIPMODE_SDIOD(cs) (((cs) & 0x7) < 6) /* SDIO || gSPI */ ++#define CST4330_CHIPMODE_USB20D(cs) (((cs) & 0x7) >= 6) /* USB || USBDA */ ++#define CST4330_CHIPMODE_SDIO(cs) (((cs) & 0x4) == 0) /* SDIO */ ++#define CST4330_CHIPMODE_GSPI(cs) (((cs) & 0x6) == 4) /* gSPI */ ++#define CST4330_CHIPMODE_USB(cs) (((cs) & 0x7) == 6) /* USB packet-oriented */ ++#define CST4330_CHIPMODE_USBDA(cs) (((cs) & 0x7) == 7) /* USB Direct Access */ ++#define CST4330_OTP_PRESENT 0x00000010 ++#define CST4330_LPO_AUTODET_EN 0x00000020 ++#define CST4330_ARMREMAP_0 0x00000040 ++#define CST4330_SPROM_PRESENT 0x00000080 /* takes priority over OTP if both set */ ++#define CST4330_ILPDIV_EN 0x00000100 ++#define CST4330_LPO_SEL 0x00000200 ++#define CST4330_RES_INIT_MODE_SHIFT 10 ++#define CST4330_RES_INIT_MODE_MASK 0x00000c00 ++#define CST4330_CBUCK_MODE_SHIFT 12 ++#define CST4330_CBUCK_MODE_MASK 0x00003000 ++#define CST4330_CBUCK_POWER_OK 0x00004000 ++#define CST4330_BB_PLL_LOCKED 0x00008000 ++#define SOCDEVRAM_BP_ADDR 0x1E000000 ++#define SOCDEVRAM_ARM_ADDR 0x00800000 ++ ++/* 4330 Chip specific PMU ChipControl register bits */ ++#define PCTL_4330_SERIAL_ENAB (1 << 24) ++ ++/* 4330 Chip specific ChipControl register bits */ ++#define CCTRL_4330_GPIO_SEL 0x00000001 /* 1=select GPIOs to be muxed out */ ++#define CCTRL_4330_ERCX_SEL 0x00000002 /* 1=select ERCX BT coex to be muxed out */ ++#define CCTRL_4330_SDIO_HOST_WAKE 0x00000004 /* SDIO: 1=configure GPIO0 for host wake */ ++#define CCTRL_4330_JTAG_DISABLE 0x00000008 /* 1=disable JTAG interface on mux'd pins */ ++ ++/* 4334 resources */ ++#define RES4334_LPLDO_PU 0 ++#define RES4334_RESET_PULLDN_DIS 1 ++#define RES4334_PMU_BG_PU 2 ++#define RES4334_HSIC_LDO_PU 3 ++#define RES4334_CBUCK_LPOM_PU 4 ++#define RES4334_CBUCK_PFM_PU 5 ++#define RES4334_CLDO_PU 6 ++#define RES4334_LPLDO2_LVM 7 ++#define RES4334_LNLDO_PU 8 ++#define RES4334_LDO3P3_PU 9 ++#define RES4334_OTP_PU 10 ++#define RES4334_XTAL_PU 11 ++#define RES4334_WL_PWRSW_PU 12 ++#define RES4334_LQ_AVAIL 13 ++#define RES4334_LOGIC_RET 14 ++#define RES4334_MEM_SLEEP 15 ++#define RES4334_MACPHY_RET 16 ++#define RES4334_WL_CORE_READY 17 ++#define RES4334_ILP_REQ 18 ++#define RES4334_ALP_AVAIL 19 ++#define RES4334_MISC_PWRSW_PU 20 ++#define RES4334_SYNTH_PWRSW_PU 21 ++#define RES4334_RX_PWRSW_PU 22 ++#define RES4334_RADIO_PU 23 ++#define RES4334_WL_PMU_PU 24 ++#define RES4334_VCO_LDO_PU 25 ++#define RES4334_AFE_LDO_PU 26 ++#define RES4334_RX_LDO_PU 27 ++#define RES4334_TX_LDO_PU 28 ++#define RES4334_HT_AVAIL 29 ++#define RES4334_MACPHY_CLK_AVAIL 30 ++ ++/* 4334 chip-specific ChipStatus register bits */ ++#define CST4334_CHIPMODE_MASK 7 ++#define CST4334_SDIO_MODE 0x00000000 ++#define CST4334_SPI_MODE 0x00000004 ++#define CST4334_HSIC_MODE 0x00000006 ++#define CST4334_BLUSB_MODE 0x00000007 ++#define CST4334_CHIPMODE_HSIC(cs) (((cs) & CST4334_CHIPMODE_MASK) == CST4334_HSIC_MODE) ++#define CST4334_OTP_PRESENT 0x00000010 ++#define CST4334_LPO_AUTODET_EN 0x00000020 ++#define CST4334_ARMREMAP_0 0x00000040 ++#define CST4334_SPROM_PRESENT 0x00000080 ++#define CST4334_ILPDIV_EN_MASK 0x00000100 ++#define CST4334_ILPDIV_EN_SHIFT 8 ++#define CST4334_LPO_SEL_MASK 0x00000200 ++#define CST4334_LPO_SEL_SHIFT 9 ++#define CST4334_RES_INIT_MODE_MASK 0x00000C00 ++#define CST4334_RES_INIT_MODE_SHIFT 10 ++ ++/* 4334 Chip specific PMU ChipControl register bits */ ++#define PCTL_4334_GPIO3_ENAB (1 << 3) ++ ++/* 4334 Chip control */ ++#define CCTRL4334_HSIC_LDO_PU (1 << 23) ++ ++/* 4324 Chip specific ChipControl1 register bits */ ++#define CCTRL1_4324_GPIO_SEL (1 << 0) /* 1=select GPIOs to be muxed out */ ++#define CCTRL1_4324_SDIO_HOST_WAKE (1 << 2) /* SDIO: 1=configure GPIO0 for host wake */ ++ ++ ++/* 4313 resources */ ++#define RES4313_BB_PU_RSRC 0 ++#define RES4313_ILP_REQ_RSRC 1 ++#define RES4313_XTAL_PU_RSRC 2 ++#define RES4313_ALP_AVAIL_RSRC 3 ++#define RES4313_RADIO_PU_RSRC 4 ++#define RES4313_BG_PU_RSRC 5 ++#define RES4313_VREG1P4_PU_RSRC 6 ++#define RES4313_AFE_PWRSW_RSRC 7 ++#define RES4313_RX_PWRSW_RSRC 8 ++#define RES4313_TX_PWRSW_RSRC 9 ++#define RES4313_BB_PWRSW_RSRC 10 ++#define RES4313_SYNTH_PWRSW_RSRC 11 ++#define RES4313_MISC_PWRSW_RSRC 12 ++#define RES4313_BB_PLL_PWRSW_RSRC 13 ++#define RES4313_HT_AVAIL_RSRC 14 ++#define RES4313_MACPHY_CLK_AVAIL_RSRC 15 ++ ++/* 4313 chip-specific ChipStatus register bits */ ++#define CST4313_SPROM_PRESENT 1 ++#define CST4313_OTP_PRESENT 2 ++#define CST4313_SPROM_OTP_SEL_MASK 0x00000002 ++#define CST4313_SPROM_OTP_SEL_SHIFT 0 ++ ++/* 4313 Chip specific ChipControl register bits */ ++#define CCTRL_4313_12MA_LED_DRIVE 0x00000007 /* 12 mA drive strengh for later 4313 */ ++ ++/* PMU respources for 4314 */ ++#define RES4314_LPLDO_PU 0 ++#define RES4314_PMU_SLEEP_DIS 1 ++#define RES4314_PMU_BG_PU 2 ++#define RES4314_CBUCK_LPOM_PU 3 ++#define RES4314_CBUCK_PFM_PU 4 ++#define RES4314_CLDO_PU 5 ++#define RES4314_LPLDO2_LVM 6 ++#define RES4314_WL_PMU_PU 7 ++#define RES4314_LNLDO_PU 8 ++#define RES4314_LDO3P3_PU 9 ++#define RES4314_OTP_PU 10 ++#define RES4314_XTAL_PU 11 ++#define RES4314_WL_PWRSW_PU 12 ++#define RES4314_LQ_AVAIL 13 ++#define RES4314_LOGIC_RET 14 ++#define RES4314_MEM_SLEEP 15 ++#define RES4314_MACPHY_RET 16 ++#define RES4314_WL_CORE_READY 17 ++#define RES4314_ILP_REQ 18 ++#define RES4314_ALP_AVAIL 19 ++#define RES4314_MISC_PWRSW_PU 20 ++#define RES4314_SYNTH_PWRSW_PU 21 ++#define RES4314_RX_PWRSW_PU 22 ++#define RES4314_RADIO_PU 23 ++#define RES4314_VCO_LDO_PU 24 ++#define RES4314_AFE_LDO_PU 25 ++#define RES4314_RX_LDO_PU 26 ++#define RES4314_TX_LDO_PU 27 ++#define RES4314_HT_AVAIL 28 ++#define RES4314_MACPHY_CLK_AVAIL 29 ++ ++/* 4314 chip-specific ChipStatus register bits */ ++#define CST4314_OTP_ENABLED 0x00200000 ++ ++/* 43228 resources */ ++#define RES43228_NOT_USED 0 ++#define RES43228_ILP_REQUEST 1 ++#define RES43228_XTAL_PU 2 ++#define RES43228_ALP_AVAIL 3 ++#define RES43228_PLL_EN 4 ++#define RES43228_HT_PHY_AVAIL 5 ++ ++/* 43228 chipstatus reg bits */ ++#define CST43228_ILP_DIV_EN 0x1 ++#define CST43228_OTP_PRESENT 0x2 ++#define CST43228_SERDES_REFCLK_PADSEL 0x4 ++#define CST43228_SDIO_MODE 0x8 ++#define CST43228_SDIO_OTP_PRESENT 0x10 ++#define CST43228_SDIO_RESET 0x20 ++ ++/* 4706 chipstatus reg bits */ ++#define CST4706_PKG_OPTION (1<<0) /* 0: full-featured package 1: low-cost package */ ++#define CST4706_SFLASH_PRESENT (1<<1) /* 0: parallel, 1: serial flash is present */ ++#define CST4706_SFLASH_TYPE (1<<2) /* 0: 8b-p/ST-s flash, 1: 16b-p/Atmal-s flash */ ++#define CST4706_MIPS_BENDIAN (1<<3) /* 0: little, 1: big endian */ ++#define CST4706_PCIE1_DISABLE (1<<5) /* PCIE1 enable strap pin */ ++ ++/* 4706 flashstrconfig reg bits */ ++#define FLSTRCF4706_MASK 0x000000ff ++#define FLSTRCF4706_SF1 0x00000001 /* 2nd serial flash present */ ++#define FLSTRCF4706_PF1 0x00000002 /* 2nd parallel flash present */ ++#define FLSTRCF4706_SF1_TYPE 0x00000004 /* 2nd serial flash type : 0 : ST, 1 : Atmel */ ++#define FLSTRCF4706_NF1 0x00000008 /* 2nd NAND flash present */ ++#define FLSTRCF4706_1ST_MADDR_SEG_MASK 0x000000f0 /* Valid value mask */ ++#define FLSTRCF4706_1ST_MADDR_SEG_4MB 0x00000010 /* 4MB */ ++#define FLSTRCF4706_1ST_MADDR_SEG_8MB 0x00000020 /* 8MB */ ++#define FLSTRCF4706_1ST_MADDR_SEG_16MB 0x00000030 /* 16MB */ ++#define FLSTRCF4706_1ST_MADDR_SEG_32MB 0x00000040 /* 32MB */ ++#define FLSTRCF4706_1ST_MADDR_SEG_64MB 0x00000050 /* 64MB */ ++#define FLSTRCF4706_1ST_MADDR_SEG_128MB 0x00000060 /* 128MB */ ++#define FLSTRCF4706_1ST_MADDR_SEG_256MB 0x00000070 /* 256MB */ ++ ++/* 4360 Chip specific ChipControl register bits */ ++#define CCTRL4360_SECI_MODE (1 << 2) ++#define CCTRL4360_BTSWCTRL_MODE (1 << 3) ++#define CCTRL4360_EXTRA_FEMCTRL_MODE (1 << 8) ++#define CCTRL4360_BT_LGCY_MODE (1 << 9) ++#define CCTRL4360_CORE2FEMCTRL4_ON (1 << 21) ++ ++/* 4360 PMU resources and chip status bits */ ++#define RES4360_REGULATOR 0 ++#define RES4360_ILP_AVAIL 1 ++#define RES4360_ILP_REQ 2 ++#define RES4360_XTAL_PU 3 ++#define RES4360_ALP_AVAIL 4 ++#define RES4360_BBPLLPWRSW_PU 5 ++#define RES4360_HT_AVAIL 6 ++#define RES4360_OTP_PU 7 ++#define RES4360_USBLDO_PU 8 ++#define RES4360_USBPLL_PWRSW_PU 9 ++#define RES4360_LQ_AVAIL 10 ++ ++#define CST4360_XTAL_40MZ 0x00000001 ++#define CST4360_SFLASH 0x00000002 ++#define CST4360_SPROM_PRESENT 0x00000004 ++#define CST4360_SFLASH_TYPE 0x00000004 ++#define CST4360_OTP_ENABLED 0x00000008 ++#define CST4360_REMAP_ROM 0x00000010 ++#define CST4360_RSRC_INIT_MODE_MASK 0x00000060 ++#define CST4360_RSRC_INIT_MODE_SHIFT 5 ++#define CST4360_ILP_DIVEN 0x00000080 ++#define CST4360_MODE_USB 0x00000100 ++#define CST4360_SPROM_SIZE_MASK 0x00000600 ++#define CST4360_SPROM_SIZE_SHIFT 9 ++#define CST4360_BBPLL_LOCK 0x00000800 ++#define CST4360_AVBBPLL_LOCK 0x00001000 ++#define CST4360_USBBBPLL_LOCK 0x00002000 ++ ++#define CCTL_4360_UART_SEL 2 ++ ++/* 4335 resources */ ++#define RES4335_LPLDO_PO 0 ++#define RES4335_PMU_BG_PU 1 ++#define RES4335_PMU_SLEEP 2 ++#define RES4335_RSVD_3 3 ++#define RES4335_CBUCK_LPOM_PU 4 ++#define RES4335_CBUCK_PFM_PU 5 ++#define RES4335_RSVD_6 6 ++#define RES4335_RSVD_7 7 ++#define RES4335_LNLDO_PU 8 ++#define RES4335_XTALLDO_PU 9 ++#define RES4335_LDO3P3_PU 10 ++#define RES4335_OTP_PU 11 ++#define RES4335_XTAL_PU 12 ++#define RES4335_SR_CLK_START 13 ++#define RES4335_LQ_AVAIL 14 ++#define RES4335_LQ_START 15 ++#define RES4335_RSVD_16 16 ++#define RES4335_WL_CORE_RDY 17 ++#define RES4335_ILP_REQ 18 ++#define RES4335_ALP_AVAIL 19 ++#define RES4335_MINI_PMU 20 ++#define RES4335_RADIO_PU 21 ++#define RES4335_SR_CLK_STABLE 22 ++#define RES4335_SR_SAVE_RESTORE 23 ++#define RES4335_SR_PHY_PWRSW 24 ++#define RES4335_SR_VDDM_PWRSW 25 ++#define RES4335_SR_SUBCORE_PWRSW 26 ++#define RES4335_SR_SLEEP 27 ++#define RES4335_HT_START 28 ++#define RES4335_HT_AVAIL 29 ++#define RES4335_MACPHY_CLKAVAIL 30 ++ ++/* 4335 Chip specific ChipStatus register bits */ ++#define CST4335_SPROM_MASK 0x00000020 ++#define CST4335_SFLASH_MASK 0x00000040 ++#define CST4335_RES_INIT_MODE_SHIFT 7 ++#define CST4335_RES_INIT_MODE_MASK 0x00000180 ++#define CST4335_CHIPMODE_MASK 0xF ++#define CST4335_CHIPMODE_SDIOD(cs) (((cs) & (1 << 0)) != 0) /* SDIO */ ++#define CST4335_CHIPMODE_GSPI(cs) (((cs) & (1 << 1)) != 0) /* gSPI */ ++#define CST4335_CHIPMODE_USB20D(cs) (((cs) & (1 << 2)) != 0) /* USB || USBDA */ ++#define CST4335_CHIPMODE_PCIE(cs) (((cs) & (1 << 3)) != 0) /* PCIE */ ++ ++/* 4335 Chip specific ChipControl1 register bits */ ++#define CCTRL1_4335_GPIO_SEL (1 << 0) /* 1=select GPIOs to be muxed out */ ++#define CCTRL1_4335_SDIO_HOST_WAKE (1 << 2) /* SDIO: 1=configure GPIO0 for host wake */ ++ ++ ++#define CR4_RAM_BASE (0x180000) ++#define PATCHTBL_SIZE (0x800) ++ ++ ++/* 4335 resources--END */ ++ ++/* GCI chipcontrol register indices */ ++#define CC_GCI_CHIPCTRL_00 (0) ++#define CC_GCI_CHIPCTRL_01 (1) ++#define CC_GCI_CHIPCTRL_02 (2) ++#define CC_GCI_CHIPCTRL_03 (3) ++#define CC_GCI_CHIPCTRL_04 (4) ++#define CC_GCI_CHIPCTRL_05 (5) ++#define CC_GCI_CHIPCTRL_06 (6) ++#define CC_GCI_CHIPCTRL_07 (7) ++#define CC_GCI_CHIPCTRL_08 (8) ++ ++#define CC_GCI_NUMCHIPCTRLREGS(cap1) ((cap1 & 0xF00) >> 8) ++ ++/* 4335 pins ++* note: only the values set as default/used are added here. ++*/ ++#define CC4335_PIN_GPIO_00 (0) ++#define CC4335_PIN_GPIO_01 (1) ++#define CC4335_PIN_GPIO_02 (2) ++#define CC4335_PIN_GPIO_03 (3) ++#define CC4335_PIN_GPIO_04 (4) ++#define CC4335_PIN_GPIO_05 (5) ++#define CC4335_PIN_GPIO_06 (6) ++#define CC4335_PIN_GPIO_07 (7) ++#define CC4335_PIN_GPIO_08 (8) ++#define CC4335_PIN_GPIO_09 (9) ++#define CC4335_PIN_GPIO_10 (10) ++#define CC4335_PIN_GPIO_11 (11) ++#define CC4335_PIN_GPIO_12 (12) ++#define CC4335_PIN_GPIO_13 (13) ++#define CC4335_PIN_GPIO_14 (14) ++#define CC4335_PIN_GPIO_15 (15) ++#define CC4335_PIN_SDIO_CLK (16) ++#define CC4335_PIN_SDIO_CMD (17) ++#define CC4335_PIN_SDIO_DATA0 (18) ++#define CC4335_PIN_SDIO_DATA1 (19) ++#define CC4335_PIN_SDIO_DATA2 (20) ++#define CC4335_PIN_SDIO_DATA3 (21) ++#define CC4335_PIN_RF_SW_CTRL_0 (22) ++#define CC4335_PIN_RF_SW_CTRL_1 (23) ++#define CC4335_PIN_RF_SW_CTRL_2 (24) ++#define CC4335_PIN_RF_SW_CTRL_3 (25) ++#define CC4335_PIN_RF_SW_CTRL_4 (26) ++#define CC4335_PIN_RF_SW_CTRL_5 (27) ++#define CC4335_PIN_RF_SW_CTRL_6 (28) ++#define CC4335_PIN_RF_SW_CTRL_7 (29) ++#define CC4335_PIN_RF_SW_CTRL_8 (30) ++#define CC4335_PIN_RF_SW_CTRL_9 (31) ++ ++/* 4335 GCI function sel values ++*/ ++#define CC4335_FNSEL_HWDEF (0) ++#define CC4335_FNSEL_SAMEASPIN (1) ++#define CC4335_FNSEL_GPIO0 (2) ++#define CC4335_FNSEL_GPIO1 (3) ++#define CC4335_FNSEL_GCI0 (4) ++#define CC4335_FNSEL_GCI1 (5) ++#define CC4335_FNSEL_UART (6) ++#define CC4335_FNSEL_SFLASH (7) ++#define CC4335_FNSEL_SPROM (8) ++#define CC4335_FNSEL_MISC0 (9) ++#define CC4335_FNSEL_MISC1 (10) ++#define CC4335_FNSEL_MISC2 (11) ++#define CC4335_FNSEL_IND (12) ++#define CC4335_FNSEL_PDN (13) ++#define CC4335_FNSEL_PUP (14) ++#define CC4335_FNSEL_TRI (15) ++ ++/* find the 4 bit mask given the bit position */ ++#define GCIMASK(pos) (((uint32)0xF) << pos) ++ ++/* get the value which can be used to directly OR with chipcontrol reg */ ++#define GCIPOSVAL(val, pos) ((((uint32)val) << pos) & GCIMASK(pos)) ++ ++/* 4335 MUX options. each nibble belongs to a setting. Non-zero value specifies a logic ++* for now only UART for bootloader. ++*/ ++#define MUXENAB4335_UART_MASK (0x0000000f) ++ ++ ++/* defines to detect active host interface in use */ ++#define CHIP_HOSTIF_USB(sih) (si_chip_hostif(sih) & CST4360_MODE_USB) ++ ++/* ++* Maximum delay for the PMU state transition in us. ++* This is an upper bound intended for spinwaits etc. ++*/ ++#define PMU_MAX_TRANSITION_DLY 20000 ++ ++/* PMU resource up transition time in ILP cycles */ ++#define PMURES_UP_TRANSITION 2 ++ ++/* ++* Information from BT to WLAN over eci_inputlo, eci_inputmi & ++* eci_inputhi register. Rev >=21 ++*/ ++/* Fields in eci_inputlo register - [0:31] */ ++#define ECI_INLO_TASKTYPE_MASK 0x0000000f /* [3:0] - 4 bits */ ++#define ECI_INLO_TASKTYPE_SHIFT 0 ++#define ECI_INLO_PKTDUR_MASK 0x000000f0 /* [7:4] - 4 bits */ ++#define ECI_INLO_PKTDUR_SHIFT 4 ++#define ECI_INLO_ROLE_MASK 0x00000100 /* [8] - 1 bits */ ++#define ECI_INLO_ROLE_SHIFT 8 ++#define ECI_INLO_MLP_MASK 0x00000e00 /* [11:9] - 3 bits */ ++#define ECI_INLO_MLP_SHIFT 9 ++#define ECI_INLO_TXPWR_MASK 0x000ff000 /* [19:12] - 8 bits */ ++#define ECI_INLO_TXPWR_SHIFT 12 ++#define ECI_INLO_RSSI_MASK 0x0ff00000 /* [27:20] - 8 bits */ ++#define ECI_INLO_RSSI_SHIFT 20 ++#define ECI_INLO_VAD_MASK 0x10000000 /* [28] - 1 bits */ ++#define ECI_INLO_VAD_SHIFT 28 ++ ++/* ++* Register eci_inputlo bitfield values. ++* - BT packet type information bits [7:0] ++*/ ++/* [3:0] - Task (link) type */ ++#define BT_ACL 0x00 ++#define BT_SCO 0x01 ++#define BT_eSCO 0x02 ++#define BT_A2DP 0x03 ++#define BT_SNIFF 0x04 ++#define BT_PAGE_SCAN 0x05 ++#define BT_INQUIRY_SCAN 0x06 ++#define BT_PAGE 0x07 ++#define BT_INQUIRY 0x08 ++#define BT_MSS 0x09 ++#define BT_PARK 0x0a ++#define BT_RSSISCAN 0x0b ++#define BT_MD_ACL 0x0c ++#define BT_MD_eSCO 0x0d ++#define BT_SCAN_WITH_SCO_LINK 0x0e ++#define BT_SCAN_WITHOUT_SCO_LINK 0x0f ++/* [7:4] = packet duration code */ ++/* [8] - Master / Slave */ ++#define BT_MASTER 0 ++#define BT_SLAVE 1 ++/* [11:9] - multi-level priority */ ++#define BT_LOWEST_PRIO 0x0 ++#define BT_HIGHEST_PRIO 0x3 ++/* [19:12] - BT transmit power */ ++/* [27:20] - BT RSSI */ ++/* [28] - VAD silence */ ++/* [31:29] - Undefined */ ++/* Register eci_inputmi values - [32:63] - none defined */ ++/* [63:32] - Undefined */ ++ ++/* Information from WLAN to BT over eci_output register. */ ++/* Fields in eci_output register - [0:31] */ ++#define ECI48_OUT_MASKMAGIC_HIWORD 0x55550000 ++#define ECI_OUT_CHANNEL_MASK(ccrev) ((ccrev) < 35 ? 0xf : (ECI48_OUT_MASKMAGIC_HIWORD | 0xf000)) ++#define ECI_OUT_CHANNEL_SHIFT(ccrev) ((ccrev) < 35 ? 0 : 12) ++#define ECI_OUT_BW_MASK(ccrev) ((ccrev) < 35 ? 0x70 : (ECI48_OUT_MASKMAGIC_HIWORD | 0xe00)) ++#define ECI_OUT_BW_SHIFT(ccrev) ((ccrev) < 35 ? 4 : 9) ++#define ECI_OUT_ANTENNA_MASK(ccrev) ((ccrev) < 35 ? 0x80 : (ECI48_OUT_MASKMAGIC_HIWORD | 0x100)) ++#define ECI_OUT_ANTENNA_SHIFT(ccrev) ((ccrev) < 35 ? 7 : 8) ++#define ECI_OUT_SIMUL_TXRX_MASK(ccrev) \ ++ ((ccrev) < 35 ? 0x10000 : (ECI48_OUT_MASKMAGIC_HIWORD | 0x80)) ++#define ECI_OUT_SIMUL_TXRX_SHIFT(ccrev) ((ccrev) < 35 ? 16 : 7) ++#define ECI_OUT_FM_DISABLE_MASK(ccrev) \ ++ ((ccrev) < 35 ? 0x40000 : (ECI48_OUT_MASKMAGIC_HIWORD | 0x40)) ++#define ECI_OUT_FM_DISABLE_SHIFT(ccrev) ((ccrev) < 35 ? 18 : 6) ++ ++/* Indicate control of ECI bits between s/w and dot11mac. ++ * 0 => FW control, 1=> MAC/ucode control ++ ++ * Current assignment (ccrev >= 35): ++ * 0 - TxConf (ucode) ++ * 38 - FM disable (wl) ++ * 39 - Allow sim rx (ucode) ++ * 40 - Num antennas (wl) ++ * 43:41 - WLAN channel exclusion BW (wl) ++ * 47:44 - WLAN channel (wl) ++ * ++ * (ccrev < 35) ++ * 15:0 - wl ++ * 16 - ++ * 18 - FM disable ++ * 30 - wl interrupt ++ * 31 - ucode interrupt ++ * others - unassigned (presumed to be with dot11mac/ucode) ++ */ ++#define ECI_MACCTRL_BITS 0xbffb0000 ++#define ECI_MACCTRLLO_BITS 0x1 ++#define ECI_MACCTRLHI_BITS 0xFF ++ ++/* SECI configuration */ ++#define SECI_MODE_UART 0x0 ++#define SECI_MODE_SECI 0x1 ++#define SECI_MODE_LEGACY_3WIRE_BT 0x2 ++#define SECI_MODE_LEGACY_3WIRE_WLAN 0x3 ++#define SECI_MODE_HALF_SECI 0x4 ++ ++#define SECI_RESET (1 << 0) ++#define SECI_RESET_BAR_UART (1 << 1) ++#define SECI_ENAB_SECI_ECI (1 << 2) ++#define SECI_ENAB_SECIOUT_DIS (1 << 3) ++#define SECI_MODE_MASK 0x7 ++#define SECI_MODE_SHIFT 4 /* (bits 5, 6, 7) */ ++#define SECI_UPD_SECI (1 << 7) ++ ++#define SECI_SIGNOFF_0 0xDB ++#define SECI_SIGNOFF_1 0 ++ ++/* seci clk_ctl_st bits */ ++#define CLKCTL_STS_SECI_CLK_REQ (1 << 8) ++#define CLKCTL_STS_SECI_CLK_AVAIL (1 << 24) ++ ++#define SECI_UART_MSR_CTS_STATE (1 << 0) ++#define SECI_UART_MSR_RTS_STATE (1 << 1) ++#define SECI_UART_SECI_IN_STATE (1 << 2) ++#define SECI_UART_SECI_IN2_STATE (1 << 3) ++ ++/* SECI UART LCR/MCR register bits */ ++#define SECI_UART_LCR_STOP_BITS (1 << 0) /* 0 - 1bit, 1 - 2bits */ ++#define SECI_UART_LCR_PARITY_EN (1 << 1) ++#define SECI_UART_LCR_PARITY (1 << 2) /* 0 - odd, 1 - even */ ++#define SECI_UART_LCR_RX_EN (1 << 3) ++#define SECI_UART_LCR_LBRK_CTRL (1 << 4) /* 1 => SECI_OUT held low */ ++#define SECI_UART_LCR_TXO_EN (1 << 5) ++#define SECI_UART_LCR_RTSO_EN (1 << 6) ++#define SECI_UART_LCR_SLIPMODE_EN (1 << 7) ++#define SECI_UART_LCR_RXCRC_CHK (1 << 8) ++#define SECI_UART_LCR_TXCRC_INV (1 << 9) ++#define SECI_UART_LCR_TXCRC_LSBF (1 << 10) ++#define SECI_UART_LCR_TXCRC_EN (1 << 11) ++ ++#define SECI_UART_MCR_TX_EN (1 << 0) ++#define SECI_UART_MCR_PRTS (1 << 1) ++#define SECI_UART_MCR_SWFLCTRL_EN (1 << 2) ++#define SECI_UART_MCR_HIGHRATE_EN (1 << 3) ++#define SECI_UART_MCR_LOOPBK_EN (1 << 4) ++#define SECI_UART_MCR_AUTO_RTS (1 << 5) ++#define SECI_UART_MCR_AUTO_TX_DIS (1 << 6) ++#define SECI_UART_MCR_BAUD_ADJ_EN (1 << 7) ++#define SECI_UART_MCR_XONOFF_RPT (1 << 9) ++ ++/* WLAN channel numbers - used from wifi.h */ ++ ++/* WLAN BW */ ++#define ECI_BW_20 0x0 ++#define ECI_BW_25 0x1 ++#define ECI_BW_30 0x2 ++#define ECI_BW_35 0x3 ++#define ECI_BW_40 0x4 ++#define ECI_BW_45 0x5 ++#define ECI_BW_50 0x6 ++#define ECI_BW_ALL 0x7 ++ ++/* WLAN - number of antenna */ ++#define WLAN_NUM_ANT1 TXANT_0 ++#define WLAN_NUM_ANT2 TXANT_1 ++ ++#endif /* _SBCHIPC_H */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/sbconfig.h b/drivers/net/ethernet/broadcom/gmac/src/include/sbconfig.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/sbconfig.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/sbconfig.h 2017-11-09 17:53:44.005292000 +0800 +@@ -0,0 +1,276 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Broadcom SiliconBackplane hardware register definitions. ++ * ++ * $Id: sbconfig.h 241182 2011-02-17 21:50:03Z $ ++ */ ++ ++#ifndef _SBCONFIG_H ++#define _SBCONFIG_H ++ ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif ++ ++/* enumeration in SB is based on the premise that cores are contiguos in the ++ * enumeration space. ++ */ ++#define SB_BUS_SIZE 0x10000 /* Each bus gets 64Kbytes for cores */ ++#define SB_BUS_BASE(b) (SI_ENUM_BASE + (b) * SB_BUS_SIZE) ++#define SB_BUS_MAXCORES (SB_BUS_SIZE / SI_CORE_SIZE) /* Max cores per bus */ ++ ++/* ++ * Sonics Configuration Space Registers. ++ */ ++#define SBCONFIGOFF 0xf00 /* core sbconfig regs are top 256bytes of regs */ ++#define SBCONFIGSIZE 256 /* sizeof (sbconfig_t) */ ++ ++#define SBIPSFLAG 0x08 ++#define SBTPSFLAG 0x18 ++#define SBTMERRLOGA 0x48 /* sonics >= 2.3 */ ++#define SBTMERRLOG 0x50 /* sonics >= 2.3 */ ++#define SBADMATCH3 0x60 ++#define SBADMATCH2 0x68 ++#define SBADMATCH1 0x70 ++#define SBIMSTATE 0x90 ++#define SBINTVEC 0x94 ++#define SBTMSTATELOW 0x98 ++#define SBTMSTATEHIGH 0x9c ++#define SBBWA0 0xa0 ++#define SBIMCONFIGLOW 0xa8 ++#define SBIMCONFIGHIGH 0xac ++#define SBADMATCH0 0xb0 ++#define SBTMCONFIGLOW 0xb8 ++#define SBTMCONFIGHIGH 0xbc ++#define SBBCONFIG 0xc0 ++#define SBBSTATE 0xc8 ++#define SBACTCNFG 0xd8 ++#define SBFLAGST 0xe8 ++#define SBIDLOW 0xf8 ++#define SBIDHIGH 0xfc ++ ++/* All the previous registers are above SBCONFIGOFF, but with Sonics 2.3, we have ++ * a few registers *below* that line. I think it would be very confusing to try ++ * and change the value of SBCONFIGOFF, so I'm definig them as absolute offsets here, ++ */ ++ ++#define SBIMERRLOGA 0xea8 ++#define SBIMERRLOG 0xeb0 ++#define SBTMPORTCONNID0 0xed8 ++#define SBTMPORTLOCK0 0xef8 ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++typedef volatile struct _sbconfig { ++ uint32 PAD[2]; ++ uint32 sbipsflag; /* initiator port ocp slave flag */ ++ uint32 PAD[3]; ++ uint32 sbtpsflag; /* target port ocp slave flag */ ++ uint32 PAD[11]; ++ uint32 sbtmerrloga; /* (sonics >= 2.3) */ ++ uint32 PAD; ++ uint32 sbtmerrlog; /* (sonics >= 2.3) */ ++ uint32 PAD[3]; ++ uint32 sbadmatch3; /* address match3 */ ++ uint32 PAD; ++ uint32 sbadmatch2; /* address match2 */ ++ uint32 PAD; ++ uint32 sbadmatch1; /* address match1 */ ++ uint32 PAD[7]; ++ uint32 sbimstate; /* initiator agent state */ ++ uint32 sbintvec; /* interrupt mask */ ++ uint32 sbtmstatelow; /* target state */ ++ uint32 sbtmstatehigh; /* target state */ ++ uint32 sbbwa0; /* bandwidth allocation table0 */ ++ uint32 PAD; ++ uint32 sbimconfiglow; /* initiator configuration */ ++ uint32 sbimconfighigh; /* initiator configuration */ ++ uint32 sbadmatch0; /* address match0 */ ++ uint32 PAD; ++ uint32 sbtmconfiglow; /* target configuration */ ++ uint32 sbtmconfighigh; /* target configuration */ ++ uint32 sbbconfig; /* broadcast configuration */ ++ uint32 PAD; ++ uint32 sbbstate; /* broadcast state */ ++ uint32 PAD[3]; ++ uint32 sbactcnfg; /* activate configuration */ ++ uint32 PAD[3]; ++ uint32 sbflagst; /* current sbflags */ ++ uint32 PAD[3]; ++ uint32 sbidlow; /* identification */ ++ uint32 sbidhigh; /* identification */ ++} sbconfig_t; ++ ++#endif /* _LANGUAGE_ASSEMBLY */ ++ ++/* sbipsflag */ ++#define SBIPS_INT1_MASK 0x3f /* which sbflags get routed to mips interrupt 1 */ ++#define SBIPS_INT1_SHIFT 0 ++#define SBIPS_INT2_MASK 0x3f00 /* which sbflags get routed to mips interrupt 2 */ ++#define SBIPS_INT2_SHIFT 8 ++#define SBIPS_INT3_MASK 0x3f0000 /* which sbflags get routed to mips interrupt 3 */ ++#define SBIPS_INT3_SHIFT 16 ++#define SBIPS_INT4_MASK 0x3f000000 /* which sbflags get routed to mips interrupt 4 */ ++#define SBIPS_INT4_SHIFT 24 ++ ++/* sbtpsflag */ ++#define SBTPS_NUM0_MASK 0x3f /* interrupt sbFlag # generated by this core */ ++#define SBTPS_F0EN0 0x40 /* interrupt is always sent on the backplane */ ++ ++/* sbtmerrlog */ ++#define SBTMEL_CM 0x00000007 /* command */ ++#define SBTMEL_CI 0x0000ff00 /* connection id */ ++#define SBTMEL_EC 0x0f000000 /* error code */ ++#define SBTMEL_ME 0x80000000 /* multiple error */ ++ ++/* sbimstate */ ++#define SBIM_PC 0xf /* pipecount */ ++#define SBIM_AP_MASK 0x30 /* arbitration policy */ ++#define SBIM_AP_BOTH 0x00 /* use both timeslaces and token */ ++#define SBIM_AP_TS 0x10 /* use timesliaces only */ ++#define SBIM_AP_TK 0x20 /* use token only */ ++#define SBIM_AP_RSV 0x30 /* reserved */ ++#define SBIM_IBE 0x20000 /* inbanderror */ ++#define SBIM_TO 0x40000 /* timeout */ ++#define SBIM_BY 0x01800000 /* busy (sonics >= 2.3) */ ++#define SBIM_RJ 0x02000000 /* reject (sonics >= 2.3) */ ++ ++/* sbtmstatelow */ ++#define SBTML_RESET 0x0001 /* reset */ ++#define SBTML_REJ_MASK 0x0006 /* reject field */ ++#define SBTML_REJ 0x0002 /* reject */ ++#define SBTML_TMPREJ 0x0004 /* temporary reject, for error recovery */ ++ ++#define SBTML_SICF_SHIFT 16 /* Shift to locate the SI control flags in sbtml */ ++ ++/* sbtmstatehigh */ ++#define SBTMH_SERR 0x0001 /* serror */ ++#define SBTMH_INT 0x0002 /* interrupt */ ++#define SBTMH_BUSY 0x0004 /* busy */ ++#define SBTMH_TO 0x0020 /* timeout (sonics >= 2.3) */ ++ ++#define SBTMH_SISF_SHIFT 16 /* Shift to locate the SI status flags in sbtmh */ ++ ++/* sbbwa0 */ ++#define SBBWA_TAB0_MASK 0xffff /* lookup table 0 */ ++#define SBBWA_TAB1_MASK 0xffff /* lookup table 1 */ ++#define SBBWA_TAB1_SHIFT 16 ++ ++/* sbimconfiglow */ ++#define SBIMCL_STO_MASK 0x7 /* service timeout */ ++#define SBIMCL_RTO_MASK 0x70 /* request timeout */ ++#define SBIMCL_RTO_SHIFT 4 ++#define SBIMCL_CID_MASK 0xff0000 /* connection id */ ++#define SBIMCL_CID_SHIFT 16 ++ ++/* sbimconfighigh */ ++#define SBIMCH_IEM_MASK 0xc /* inband error mode */ ++#define SBIMCH_TEM_MASK 0x30 /* timeout error mode */ ++#define SBIMCH_TEM_SHIFT 4 ++#define SBIMCH_BEM_MASK 0xc0 /* bus error mode */ ++#define SBIMCH_BEM_SHIFT 6 ++ ++/* sbadmatch0 */ ++#define SBAM_TYPE_MASK 0x3 /* address type */ ++#define SBAM_AD64 0x4 /* reserved */ ++#define SBAM_ADINT0_MASK 0xf8 /* type0 size */ ++#define SBAM_ADINT0_SHIFT 3 ++#define SBAM_ADINT1_MASK 0x1f8 /* type1 size */ ++#define SBAM_ADINT1_SHIFT 3 ++#define SBAM_ADINT2_MASK 0x1f8 /* type2 size */ ++#define SBAM_ADINT2_SHIFT 3 ++#define SBAM_ADEN 0x400 /* enable */ ++#define SBAM_ADNEG 0x800 /* negative decode */ ++#define SBAM_BASE0_MASK 0xffffff00 /* type0 base address */ ++#define SBAM_BASE0_SHIFT 8 ++#define SBAM_BASE1_MASK 0xfffff000 /* type1 base address for the core */ ++#define SBAM_BASE1_SHIFT 12 ++#define SBAM_BASE2_MASK 0xffff0000 /* type2 base address for the core */ ++#define SBAM_BASE2_SHIFT 16 ++ ++/* sbtmconfiglow */ ++#define SBTMCL_CD_MASK 0xff /* clock divide */ ++#define SBTMCL_CO_MASK 0xf800 /* clock offset */ ++#define SBTMCL_CO_SHIFT 11 ++#define SBTMCL_IF_MASK 0xfc0000 /* interrupt flags */ ++#define SBTMCL_IF_SHIFT 18 ++#define SBTMCL_IM_MASK 0x3000000 /* interrupt mode */ ++#define SBTMCL_IM_SHIFT 24 ++ ++/* sbtmconfighigh */ ++#define SBTMCH_BM_MASK 0x3 /* busy mode */ ++#define SBTMCH_RM_MASK 0x3 /* retry mode */ ++#define SBTMCH_RM_SHIFT 2 ++#define SBTMCH_SM_MASK 0x30 /* stop mode */ ++#define SBTMCH_SM_SHIFT 4 ++#define SBTMCH_EM_MASK 0x300 /* sb error mode */ ++#define SBTMCH_EM_SHIFT 8 ++#define SBTMCH_IM_MASK 0xc00 /* int mode */ ++#define SBTMCH_IM_SHIFT 10 ++ ++/* sbbconfig */ ++#define SBBC_LAT_MASK 0x3 /* sb latency */ ++#define SBBC_MAX0_MASK 0xf0000 /* maxccntr0 */ ++#define SBBC_MAX0_SHIFT 16 ++#define SBBC_MAX1_MASK 0xf00000 /* maxccntr1 */ ++#define SBBC_MAX1_SHIFT 20 ++ ++/* sbbstate */ ++#define SBBS_SRD 0x1 /* st reg disable */ ++#define SBBS_HRD 0x2 /* hold reg disable */ ++ ++/* sbidlow */ ++#define SBIDL_CS_MASK 0x3 /* config space */ ++#define SBIDL_AR_MASK 0x38 /* # address ranges supported */ ++#define SBIDL_AR_SHIFT 3 ++#define SBIDL_SYNCH 0x40 /* sync */ ++#define SBIDL_INIT 0x80 /* initiator */ ++#define SBIDL_MINLAT_MASK 0xf00 /* minimum backplane latency */ ++#define SBIDL_MINLAT_SHIFT 8 ++#define SBIDL_MAXLAT 0xf000 /* maximum backplane latency */ ++#define SBIDL_MAXLAT_SHIFT 12 ++#define SBIDL_FIRST 0x10000 /* this initiator is first */ ++#define SBIDL_CW_MASK 0xc0000 /* cycle counter width */ ++#define SBIDL_CW_SHIFT 18 ++#define SBIDL_TP_MASK 0xf00000 /* target ports */ ++#define SBIDL_TP_SHIFT 20 ++#define SBIDL_IP_MASK 0xf000000 /* initiator ports */ ++#define SBIDL_IP_SHIFT 24 ++#define SBIDL_RV_MASK 0xf0000000 /* sonics backplane revision code */ ++#define SBIDL_RV_SHIFT 28 ++#define SBIDL_RV_2_2 0x00000000 /* version 2.2 or earlier */ ++#define SBIDL_RV_2_3 0x10000000 /* version 2.3 */ ++ ++/* sbidhigh */ ++#define SBIDH_RC_MASK 0x000f /* revision code */ ++#define SBIDH_RCE_MASK 0x7000 /* revision code extension field */ ++#define SBIDH_RCE_SHIFT 8 ++#define SBCOREREV(sbidh) \ ++ ((((sbidh) & SBIDH_RCE_MASK) >> SBIDH_RCE_SHIFT) | ((sbidh) & SBIDH_RC_MASK)) ++#define SBIDH_CC_MASK 0x8ff0 /* core code */ ++#define SBIDH_CC_SHIFT 4 ++#define SBIDH_VC_MASK 0xffff0000 /* vendor code */ ++#define SBIDH_VC_SHIFT 16 ++ ++#define SB_COMMIT 0xfd8 /* update buffered registers value */ ++ ++/* vendor codes */ ++#define SB_VEND_BCM 0x4243 /* Broadcom's SB vendor code */ ++ ++#endif /* _SBCONFIG_H */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/sbhndarm.h b/drivers/net/ethernet/broadcom/gmac/src/include/sbhndarm.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/sbhndarm.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/sbhndarm.h 2017-11-09 17:53:44.005307000 +0800 +@@ -0,0 +1,293 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Broadcom SiliconBackplane ARM definitions ++ * ++ * $Id: sbhndarm.h 325951 2012-04-05 06:03:27Z $ ++ */ ++ ++#ifndef _sbhndarm_h_ ++#define _sbhndarm_h_ ++ ++#include ++#include ++ ++/* register offsets */ ++#define ARM7_CORECTL 0 ++ ++/* bits in corecontrol */ ++#define ACC_FORCED_RST 0x1 ++#define ACC_SERRINT 0x2 ++#define ACC_NOTSLEEPINGCLKREQ_SHIFT 24 ++ ++/* arm resetlog */ ++#define SBRESETLOG 0x1 ++#define SERRORLOG 0x2 ++ ++/* arm core-specific control flags */ ++#define SICF_REMAP_MSK 0x001c ++#define SICF_REMAP_NONE 0 ++#define SICF_REMAP_ROM 0x0004 ++#define SIFC_REMAP_FLASH 0x0008 ++ ++/* misc core-specific defines */ ++#if defined(__ARM_ARCH_4T__) ++/* arm7tdmi-s */ ++/* backplane related stuff */ ++#define ARM_CORE_ID ARM7S_CORE_ID /* arm coreid */ ++#define SI_ARM_ROM SI_ARM7S_ROM /* ROM backplane/system address */ ++#define SI_ARM_SRAM2 SI_ARM7S_SRAM2 /* RAM backplane address when remap is 1 or 2 */ ++#elif defined(__ARM_ARCH_7M__) ++/* cortex-m3 */ ++/* backplane related stuff */ ++#define ARM_CORE_ID ARMCM3_CORE_ID /* arm coreid */ ++#define SI_ARM_ROM SI_ARMCM3_ROM /* ROM backplane/system address */ ++#define SI_ARM_SRAM2 SI_ARMCM3_SRAM2 /* RAM backplane address when remap is 1 or 2 */ ++/* core registers offsets */ ++#define ARMCM3_CYCLECNT 0x90 /* Cortex-M3 core registers offsets */ ++#define ARMCM3_INTTIMER 0x94 ++#define ARMCM3_INTMASK 0x98 ++#define ARMCM3_INTSTATUS 0x9c ++/* interrupt/exception */ ++#define ARMCM3_NUMINTS 16 /* # of external interrupts */ ++#define ARMCM3_INTALL ((1 << ARMCM3_NUMINTS) - 1) /* Interrupt mask */ ++#define ARMCM3_FAULTMASK 0x40000000 /* Master fault enable/disable */ ++#define ARMCM3_PRIMASK 0x80000000 /* Master interrupt enable/disable */ ++#define ARMCM3_SHARED_INT 0 /* Interrupt shared by multiple cores */ ++#define ARMCM3_INT(i) (1 << (i)) /* Individual interrupt enable/disable */ ++/* compatible with arm7tdmi-s */ ++#define PS_I ARMCM3_PRIMASK ++#define PS_F ARMCM3_FAULTMASK ++/* intmask/intstatus bits */ ++#define ARMCM3_INTMASK_TIMER 0x1 ++#define ARMCM3_INTMASK_SYSRESET 0x4 ++#define ARMCM3_INTMASK_LOCKUP 0x8 ++ ++/* ++ * Overlay Support in Rev 5 ++ */ ++#define ARMCM3_OVL_VALID_SHIFT 0 ++#define ARMCM3_OVL_VALID 1 ++#define ARMCM3_OVL_SZ_SHIFT 1 ++#define ARMCM3_OVL_SZ_MASK 0x0000000e ++#define ARMCM3_OVL_SZ_512B 0 /* 512B */ ++#define ARMCM3_OVL_SZ_1KB 1 /* 1KB */ ++#define ARMCM3_OVL_SZ_2KB 2 /* 2KB */ ++#define ARMCM3_OVL_SZ_4KB 3 /* 4KB */ ++#define ARMCM3_OVL_SZ_8KB 4 /* 8KB */ ++#define ARMCM3_OVL_SZ_16KB 5 /* 16KB */ ++#define ARMCM3_OVL_SZ_32KB 6 /* 32KB */ ++#define ARMCM3_OVL_SZ_64KB 7 /* 64KB */ ++#define ARMCM3_OVL_ADDR_SHIFT 9 ++#define ARMCM3_OVL_ADDR_MASK 0x003FFE00 ++#define ARMCM3_OVL_MAX 16 ++ ++#elif defined(__ARM_ARCH_7R__) ++/* cortex-r4 */ ++/* backplane related stuff */ ++#define ARM_CORE_ID ARMCR4_CORE_ID /* arm coreid */ ++#define SI_ARM_ROM SI_ARMCR4_ROM /* ROM backplane/system address */ ++#define SI_ARM_SRAM2 0x0 /* In the cr4 the RAM is just not available ++ * when remap is 1 ++ */ ++ ++/* core registers offsets */ ++#define ARMCR4_CORECTL 0 ++#define ARMCR4_CORECAP 4 ++#define ARMCR4_COREST 8 ++ ++#define ARMCR4_FIQRSTATUS 0x10 ++#define ARMCR4_FIQMASK 0x14 ++#define ARMCR4_IRQMASK 0x18 ++ ++#define ARMCR4_INTSTATUS 0x20 ++#define ARMCR4_INTMASK 0x24 ++#define ARMCR4_CYCLECNT 0x28 ++#define ARMCR4_INTTIMER 0x2c ++ ++#define ARMCR4_GPIOSEL 0x30 ++#define ARMCR4_GPIOEN 0x34 ++ ++#define ARMCR4_BANKIDX 0x40 ++#define ARMCR4_BANKINFO 0x44 ++#define ARMCR4_BANKSTBY 0x48 ++#define ARMCR4_BANKPDA 0x4c ++ ++#define ARMCR4_TCAMPATCHCTRL 0x68 ++#define ARMCR4_TCAMPATCHTBLBASEADDR 0x6C ++#define ARMCR4_TCAMCMDREG 0x70 ++#define ARMCR4_TCAMDATAREG 0x74 ++#define ARMCR4_TCAMBANKXMASKREG 0x78 ++ ++#define ARMCR4_ROMNB_MASK 0xf00 ++#define ARMCR4_ROMNB_SHIFT 8 ++#define ARMCR4_TCBBNB_MASK 0xf0 ++#define ARMCR4_TCBBNB_SHIFT 4 ++#define ARMCR4_TCBANB_MASK 0xf ++#define ARMCR4_TCBANB_SHIFT 0 ++ ++#define ARMCR4_MT_MASK 0x300 ++#define ARMCR4_MT_SHIFT 8 ++#define ARMCR4_MT_ROM 0x100 ++#define ARMCR4_MT_RAM 0 ++ ++#define ARMCR4_BSZ_MASK 0x3f ++#define ARMCR4_BSZ_MULT 8192 ++ ++#define ARMCR4_TCAM_ENABLE (1 << 31) ++#define ARMCR4_TCAM_CLKENAB (1 << 30) ++#define ARMCR4_TCAM_PATCHCNT_MASK 0xf ++ ++#define ARMCR4_TCAM_CMD_DONE (1 << 31) ++#define ARMCR4_TCAM_MATCH (1 << 24) ++#define ARMCR4_TCAM_OPCODE_MASK (3 << 16) ++#define ARMCR4_TCAM_OPCODE_SHIFT 16 ++#define ARMCR4_TCAM_ADDR_MASK 0xffff ++#define ARMCR4_TCAM_NONE (0 << ARMCR4_TCAM_OPCODE_SHIFT) ++#define ARMCR4_TCAM_READ (1 << ARMCR4_TCAM_OPCODE_SHIFT) ++#define ARMCR4_TCAM_WRITE (2 << ARMCR4_TCAM_OPCODE_SHIFT) ++#define ARMCR4_TCAM_COMPARE (3 << ARMCR4_TCAM_OPCODE_SHIFT) ++#define ARMCR4_TCAM_CMD_DONE_DLY 1000 ++ ++#define ARMCR4_DATA_MASK (~0x7) ++#define ARMCR4_DATA_VALID (1 << 0) ++ ++ ++/* arm core-specific conrol flags */ ++#define SICF_CPUHALT 0x0020 ++#define SICF_UPDATEFW 0x0040 ++ ++/* arm core-specific status flags */ ++#define SISF_SDRENABLE 0x0001 ++#define SISF_TCMPROT 0x0002 ++ ++#define CHIP_SDRENABLE(sih) (sih->boardflags2 & BFL2_SDR_EN) ++#define CHIP_TCMPROTENAB(sih) (si_arm_sflags(sih) & SISF_TCMPROT) ++ ++#elif defined(__ARM_ARCH_7A__) ++/* backplane related stuff */ ++#define ARM_CORE_ID ARMCA9_CORE_ID /* arm coreid */ ++ ++#else /* !__ARM_ARCH_4T__ && !__ARM_ARCH_7M__ && !__ARM_ARCH_7R__ */ ++#error Unrecognized ARM Architecture ++#endif /* !__ARM_ARCH_4T__ && !__ARM_ARCH_7M__ && !__ARM_ARCH_7R__ */ ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif /* PAD */ ++ ++#if defined(__ARM_ARCH_4T__) ++/* arm7tdmi-s */ ++typedef volatile struct { ++ uint32 corecontrol; /* 0 */ ++ uint32 sleepcontrol; /* 4 */ ++ uint32 PAD; ++ uint32 biststatus; /* 0xc */ ++ uint32 firqstatus; /* 0x10 */ ++ uint32 fiqmask; /* 0x14 */ ++ uint32 irqmask; /* 0x18 */ ++ uint32 PAD; ++ uint32 resetlog; /* 0x20 */ ++ uint32 gpioselect; /* 0x24 */ ++ uint32 gpioenable; /* 0x28 */ ++ uint32 PAD; ++ uint32 bpaddrlo; /* 0x30 */ ++ uint32 bpaddrhi; /* 0x34 */ ++ uint32 bpdata; /* 0x38 */ ++ uint32 bpindaccess; /* 0x3c */ ++ uint32 PAD[104]; ++ uint32 clk_ctl_st; /* 0x1e0 */ ++ uint32 hw_war; /* 0x1e4 */ ++} armregs_t; ++#define ARMREG(regs, reg) (&((armregs_t *)regs)->reg) ++#endif /* __ARM_ARCH_4T__ */ ++ ++#if defined(__ARM_ARCH_7M__) ++/* cortex-m3 */ ++typedef volatile struct { ++ uint32 corecontrol; /* 0x0 */ ++ uint32 corestatus; /* 0x4 */ ++ uint32 PAD[1]; ++ uint32 biststatus; /* 0xc */ ++ uint32 nmiisrst; /* 0x10 */ ++ uint32 nmimask; /* 0x14 */ ++ uint32 isrmask; /* 0x18 */ ++ uint32 PAD[1]; ++ uint32 resetlog; /* 0x20 */ ++ uint32 gpioselect; /* 0x24 */ ++ uint32 gpioenable; /* 0x28 */ ++ uint32 PAD[1]; ++ uint32 bpaddrlo; /* 0x30 */ ++ uint32 bpaddrhi; /* 0x34 */ ++ uint32 bpdata; /* 0x38 */ ++ uint32 bpindaccess; /* 0x3c */ ++ uint32 ovlidx; /* 0x40 */ ++ uint32 ovlmatch; /* 0x44 */ ++ uint32 ovladdr; /* 0x48 */ ++ uint32 PAD[13]; ++ uint32 bwalloc; /* 0x80 */ ++ uint32 PAD[3]; ++ uint32 cyclecnt; /* 0x90 */ ++ uint32 inttimer; /* 0x94 */ ++ uint32 intmask; /* 0x98 */ ++ uint32 intstatus; /* 0x9c */ ++ uint32 PAD[80]; ++ uint32 clk_ctl_st; /* 0x1e0 */ ++} cm3regs_t; ++#define ARMREG(regs, reg) (&((cm3regs_t *)regs)->reg) ++#endif /* __ARM_ARCH_7M__ */ ++ ++#if defined(__ARM_ARCH_7R__) ++/* cortex-R4 */ ++typedef volatile struct { ++ uint32 corecontrol; /* 0x0 */ ++ uint32 corecapabilities; /* 0x4 */ ++ uint32 corestatus; /* 0x8 */ ++ uint32 biststatus; /* 0xc */ ++ uint32 nmiisrst; /* 0x10 */ ++ uint32 nmimask; /* 0x14 */ ++ uint32 isrmask; /* 0x18 */ ++ uint32 PAD[1]; ++ uint32 intstatus; /* 0x20 */ ++ uint32 intmask; /* 0x24 */ ++ uint32 cyclecnt; /* 0x28 */ ++ uint32 inttimer; /* 0x2c */ ++ uint32 gpioselect; /* 0x30 */ ++ uint32 gpioenable; /* 0x34 */ ++ uint32 PAD[2]; ++ uint32 bankidx; /* 0x40 */ ++ uint32 bankinfo; /* 0x44 */ ++ uint32 bankstbyctl; /* 0x48 */ ++ uint32 bankpda; /* 0x4c */ ++ uint32 PAD[6]; ++ uint32 tcampatchctrl; /* 0x68 */ ++ uint32 tcampatchtblbaseaddr; /* 0x6c */ ++ uint32 tcamcmdreg; /* 0x70 */ ++ uint32 tcamdatareg; /* 0x74 */ ++ uint32 tcambankxmaskreg; /* 0x78 */ ++ uint32 PAD[89]; ++ uint32 clk_ctl_st; /* 0x1e0 */ ++} cr4regs_t; ++#define ARMREG(regs, reg) (&((cr4regs_t *)regs)->reg) ++#endif /* __ARM_ARCH_7R__ */ ++ ++#endif /* _LANGUAGE_ASSEMBLY */ ++ ++#endif /* _sbhndarm_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/sbhnddma.h b/drivers/net/ethernet/broadcom/gmac/src/include/sbhnddma.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/sbhnddma.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/sbhnddma.h 2017-11-09 17:53:44.006300000 +0800 +@@ -0,0 +1,403 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Generic Broadcom Home Networking Division (HND) DMA engine HW interface ++ * This supports the following chips: BCM42xx, 44xx, 47xx . ++ * ++ * $Id: sbhnddma.h 321146 2012-03-14 08:27:23Z $ ++ */ ++ ++#ifndef _sbhnddma_h_ ++#define _sbhnddma_h_ ++ ++/* DMA structure: ++ * support two DMA engines: 32 bits address or 64 bit addressing ++ * basic DMA register set is per channel(transmit or receive) ++ * a pair of channels is defined for convenience ++ */ ++ ++ ++/* 32 bits addressing */ ++ ++/* dma registers per channel(xmt or rcv) */ ++typedef volatile struct { ++ uint32 control; /* enable, et al */ ++ uint32 addr; /* descriptor ring base address (4K aligned) */ ++ uint32 ptr; /* last descriptor posted to chip */ ++ uint32 status; /* current active descriptor, et al */ ++} dma32regs_t; ++ ++typedef volatile struct { ++ dma32regs_t xmt; /* dma tx channel */ ++ dma32regs_t rcv; /* dma rx channel */ ++} dma32regp_t; ++ ++typedef volatile struct { /* diag access */ ++ uint32 fifoaddr; /* diag address */ ++ uint32 fifodatalow; /* low 32bits of data */ ++ uint32 fifodatahigh; /* high 32bits of data */ ++ uint32 pad; /* reserved */ ++} dma32diag_t; ++ ++/* ++ * DMA Descriptor ++ * Descriptors are only read by the hardware, never written back. ++ */ ++typedef volatile struct { ++ uint32 ctrl; /* misc control bits & bufcount */ ++ uint32 addr; /* data buffer address */ ++} dma32dd_t; ++ ++/* ++ * Each descriptor ring must be 4096byte aligned, and fit within a single 4096byte page. ++ */ ++#define D32RINGALIGN_BITS 12 ++#define D32MAXRINGSZ (1 << D32RINGALIGN_BITS) ++#define D32RINGALIGN (1 << D32RINGALIGN_BITS) ++ ++#define D32MAXDD (D32MAXRINGSZ / sizeof (dma32dd_t)) ++ ++/* transmit channel control */ ++#define XC_XE ((uint32)1 << 0) /* transmit enable */ ++#define XC_SE ((uint32)1 << 1) /* transmit suspend request */ ++#define XC_LE ((uint32)1 << 2) /* loopback enable */ ++#define XC_FL ((uint32)1 << 4) /* flush request */ ++#define XC_MR_MASK 0x000000C0 /* Multiple outstanding reads */ ++#define XC_MR_SHIFT 6 ++#define XC_PD ((uint32)1 << 11) /* parity check disable */ ++#define XC_AE ((uint32)3 << 16) /* address extension bits */ ++#define XC_AE_SHIFT 16 ++#define XC_BL_MASK 0x001C0000 /* BurstLen bits */ ++#define XC_BL_SHIFT 18 ++#define XC_PC_MASK 0x00E00000 /* Prefetch control */ ++#define XC_PC_SHIFT 21 ++#define XC_PT_MASK 0x03000000 /* Prefetch threshold */ ++#define XC_PT_SHIFT 24 ++ ++/* Multiple outstanding reads */ ++#define DMA_MR_1 0 ++#define DMA_MR_2 1 ++/* 2, 3: reserved */ ++ ++/* DMA Burst Length in bytes */ ++#define DMA_BL_16 0 ++#define DMA_BL_32 1 ++#define DMA_BL_64 2 ++#define DMA_BL_128 3 ++#define DMA_BL_256 4 ++#define DMA_BL_512 5 ++#define DMA_BL_1024 6 ++ ++/* Prefetch control */ ++#define DMA_PC_0 0 ++#define DMA_PC_4 1 ++#define DMA_PC_8 2 ++#define DMA_PC_16 3 ++/* others: reserved */ ++ ++/* Prefetch threshold */ ++#define DMA_PT_1 0 ++#define DMA_PT_2 1 ++#define DMA_PT_4 2 ++#define DMA_PT_8 3 ++ ++/* transmit descriptor table pointer */ ++#define XP_LD_MASK 0xfff /* last valid descriptor */ ++ ++/* transmit channel status */ ++#define XS_CD_MASK 0x0fff /* current descriptor pointer */ ++#define XS_XS_MASK 0xf000 /* transmit state */ ++#define XS_XS_SHIFT 12 ++#define XS_XS_DISABLED 0x0000 /* disabled */ ++#define XS_XS_ACTIVE 0x1000 /* active */ ++#define XS_XS_IDLE 0x2000 /* idle wait */ ++#define XS_XS_STOPPED 0x3000 /* stopped */ ++#define XS_XS_SUSP 0x4000 /* suspend pending */ ++#define XS_XE_MASK 0xf0000 /* transmit errors */ ++#define XS_XE_SHIFT 16 ++#define XS_XE_NOERR 0x00000 /* no error */ ++#define XS_XE_DPE 0x10000 /* descriptor protocol error */ ++#define XS_XE_DFU 0x20000 /* data fifo underrun */ ++#define XS_XE_BEBR 0x30000 /* bus error on buffer read */ ++#define XS_XE_BEDA 0x40000 /* bus error on descriptor access */ ++#define XS_AD_MASK 0xfff00000 /* active descriptor */ ++#define XS_AD_SHIFT 20 ++ ++/* receive channel control */ ++#define RC_RE ((uint32)1 << 0) /* receive enable */ ++#define RC_RO_MASK 0xfe /* receive frame offset */ ++#define RC_RO_SHIFT 1 ++#define RC_FM ((uint32)1 << 8) /* direct fifo receive (pio) mode */ ++#define RC_SH ((uint32)1 << 9) /* separate rx header descriptor enable */ ++#define RC_OC ((uint32)1 << 10) /* overflow continue */ ++#define RC_PD ((uint32)1 << 11) /* parity check disable */ ++#define RC_AE ((uint32)3 << 16) /* address extension bits */ ++#define RC_AE_SHIFT 16 ++#define RC_BL_MASK 0x001C0000 /* BurstLen bits */ ++#define RC_BL_SHIFT 18 ++#define RC_PC_MASK 0x00E00000 /* Prefetch control */ ++#define RC_PC_SHIFT 21 ++#define RC_PT_MASK 0x03000000 /* Prefetch threshold */ ++#define RC_PT_SHIFT 24 ++ ++/* receive descriptor table pointer */ ++#define RP_LD_MASK 0xfff /* last valid descriptor */ ++ ++/* receive channel status */ ++#define RS_CD_MASK 0x0fff /* current descriptor pointer */ ++#define RS_RS_MASK 0xf000 /* receive state */ ++#define RS_RS_SHIFT 12 ++#define RS_RS_DISABLED 0x0000 /* disabled */ ++#define RS_RS_ACTIVE 0x1000 /* active */ ++#define RS_RS_IDLE 0x2000 /* idle wait */ ++#define RS_RS_STOPPED 0x3000 /* reserved */ ++#define RS_RE_MASK 0xf0000 /* receive errors */ ++#define RS_RE_SHIFT 16 ++#define RS_RE_NOERR 0x00000 /* no error */ ++#define RS_RE_DPE 0x10000 /* descriptor protocol error */ ++#define RS_RE_DFO 0x20000 /* data fifo overflow */ ++#define RS_RE_BEBW 0x30000 /* bus error on buffer write */ ++#define RS_RE_BEDA 0x40000 /* bus error on descriptor access */ ++#define RS_AD_MASK 0xfff00000 /* active descriptor */ ++#define RS_AD_SHIFT 20 ++ ++/* fifoaddr */ ++#define FA_OFF_MASK 0xffff /* offset */ ++#define FA_SEL_MASK 0xf0000 /* select */ ++#define FA_SEL_SHIFT 16 ++#define FA_SEL_XDD 0x00000 /* transmit dma data */ ++#define FA_SEL_XDP 0x10000 /* transmit dma pointers */ ++#define FA_SEL_RDD 0x40000 /* receive dma data */ ++#define FA_SEL_RDP 0x50000 /* receive dma pointers */ ++#define FA_SEL_XFD 0x80000 /* transmit fifo data */ ++#define FA_SEL_XFP 0x90000 /* transmit fifo pointers */ ++#define FA_SEL_RFD 0xc0000 /* receive fifo data */ ++#define FA_SEL_RFP 0xd0000 /* receive fifo pointers */ ++#define FA_SEL_RSD 0xe0000 /* receive frame status data */ ++#define FA_SEL_RSP 0xf0000 /* receive frame status pointers */ ++ ++/* descriptor control flags */ ++#define CTRL_BC_MASK 0x00001fff /* buffer byte count, real data len must <= 4KB */ ++#define CTRL_AE ((uint32)3 << 16) /* address extension bits */ ++#define CTRL_AE_SHIFT 16 ++#define CTRL_PARITY ((uint32)3 << 18) /* parity bit */ ++#define CTRL_EOT ((uint32)1 << 28) /* end of descriptor table */ ++#define CTRL_IOC ((uint32)1 << 29) /* interrupt on completion */ ++#define CTRL_EOF ((uint32)1 << 30) /* end of frame */ ++#define CTRL_SOF ((uint32)1 << 31) /* start of frame */ ++ ++/* control flags in the range [27:20] are core-specific and not defined here */ ++#define CTRL_CORE_MASK 0x0ff00000 ++ ++/* 64 bits addressing */ ++ ++/* dma registers per channel(xmt or rcv) */ ++typedef volatile struct { ++ uint32 control; /* enable, et al */ ++ uint32 ptr; /* last descriptor posted to chip */ ++ uint32 addrlow; /* descriptor ring base address low 32-bits (8K aligned) */ ++ uint32 addrhigh; /* descriptor ring base address bits 63:32 (8K aligned) */ ++ uint32 status0; /* current descriptor, xmt state */ ++ uint32 status1; /* active descriptor, xmt error */ ++} dma64regs_t; ++ ++typedef volatile struct { ++ dma64regs_t tx; /* dma64 tx channel */ ++ dma64regs_t rx; /* dma64 rx channel */ ++} dma64regp_t; ++ ++typedef volatile struct { /* diag access */ ++ uint32 fifoaddr; /* diag address */ ++ uint32 fifodatalow; /* low 32bits of data */ ++ uint32 fifodatahigh; /* high 32bits of data */ ++ uint32 pad; /* reserved */ ++} dma64diag_t; ++ ++/* ++ * DMA Descriptor ++ * Descriptors are only read by the hardware, never written back. ++ */ ++typedef volatile struct { ++ uint32 ctrl1; /* misc control bits */ ++ uint32 ctrl2; /* buffer count and address extension */ ++ uint32 addrlow; /* memory address of the date buffer, bits 31:0 */ ++ uint32 addrhigh; /* memory address of the date buffer, bits 63:32 */ ++} dma64dd_t; ++ ++/* ++ * Each descriptor ring must be 8kB aligned, and fit within a contiguous 8kB physical addresss. ++ */ ++#define D64RINGALIGN_BITS 13 ++#define D64MAXRINGSZ (1 << D64RINGALIGN_BITS) ++#define D64RINGBOUNDARY (1 << D64RINGALIGN_BITS) ++ ++#define D64MAXDD (D64MAXRINGSZ / sizeof (dma64dd_t)) ++ ++/* for cores with large descriptor ring support, descriptor ring size can be up to 4096 */ ++#define D64MAXDD_LARGE ((1 << 16) / sizeof (dma64dd_t)) ++ ++/* for cores with large descriptor ring support (4k descriptors), descriptor ring cannot cross ++ * 64K boundary ++ */ ++#define D64RINGBOUNDARY_LARGE (1 << 16) ++ ++/* ++ * Default DMA Burstlen values for USBRev >= 12 and SDIORev >= 11. ++ * When this field contains the value N, the burst length is 2**(N + 4) bytes. ++ */ ++#define D64_DEF_USBBURSTLEN 2 ++#define D64_DEF_SDIOBURSTLEN 1 ++ ++ ++#ifndef D64_USBBURSTLEN ++#define D64_USBBURSTLEN DMA_BL_64 ++#endif ++#ifndef D64_SDIOBURSTLEN ++#define D64_SDIOBURSTLEN DMA_BL_32 ++#endif ++ ++/* transmit channel control */ ++#define D64_XC_XE 0x00000001 /* transmit enable */ ++#define D64_XC_SE 0x00000002 /* transmit suspend request */ ++#define D64_XC_LE 0x00000004 /* loopback enable */ ++#define D64_XC_FL 0x00000010 /* flush request */ ++#define D64_XC_MR_MASK 0x000000C0 /* Multiple outstanding reads */ ++#define D64_XC_MR_SHIFT 6 ++#define D64_XC_PD 0x00000800 /* parity check disable */ ++#define D64_XC_AE 0x00030000 /* address extension bits */ ++#define D64_XC_AE_SHIFT 16 ++#define D64_XC_BL_MASK 0x001C0000 /* BurstLen bits */ ++#define D64_XC_BL_SHIFT 18 ++#define D64_XC_PC_MASK 0x00E00000 /* Prefetch control */ ++#define D64_XC_PC_SHIFT 21 ++#define D64_XC_PT_MASK 0x03000000 /* Prefetch threshold */ ++#define D64_XC_PT_SHIFT 24 ++ ++/* transmit descriptor table pointer */ ++#define D64_XP_LD_MASK 0x00001fff /* last valid descriptor */ ++ ++/* transmit channel status */ ++#define D64_XS0_CD_MASK 0x00001fff /* current descriptor pointer */ ++#define D64_XS0_XS_MASK 0xf0000000 /* transmit state */ ++#define D64_XS0_XS_SHIFT 28 ++#define D64_XS0_XS_DISABLED 0x00000000 /* disabled */ ++#define D64_XS0_XS_ACTIVE 0x10000000 /* active */ ++#define D64_XS0_XS_IDLE 0x20000000 /* idle wait */ ++#define D64_XS0_XS_STOPPED 0x30000000 /* stopped */ ++#define D64_XS0_XS_SUSP 0x40000000 /* suspend pending */ ++ ++#define D64_XS1_AD_MASK 0x00001fff /* active descriptor */ ++#define D64_XS1_XE_MASK 0xf0000000 /* transmit errors */ ++#define D64_XS1_XE_SHIFT 28 ++#define D64_XS1_XE_NOERR 0x00000000 /* no error */ ++#define D64_XS1_XE_DPE 0x10000000 /* descriptor protocol error */ ++#define D64_XS1_XE_DFU 0x20000000 /* data fifo underrun */ ++#define D64_XS1_XE_DTE 0x30000000 /* data transfer error */ ++#define D64_XS1_XE_DESRE 0x40000000 /* descriptor read error */ ++#define D64_XS1_XE_COREE 0x50000000 /* core error */ ++ ++/* receive channel control */ ++#define D64_RC_RE 0x00000001 /* receive enable */ ++#define D64_RC_RO_MASK 0x000000fe /* receive frame offset */ ++#define D64_RC_RO_SHIFT 1 ++#define D64_RC_FM 0x00000100 /* direct fifo receive (pio) mode */ ++#define D64_RC_SH 0x00000200 /* separate rx header descriptor enable */ ++#define D64_RC_OC 0x00000400 /* overflow continue */ ++#define D64_RC_PD 0x00000800 /* parity check disable */ ++#define D64_RC_GE 0x00004000 /* Glom enable */ ++#define D64_RC_AE 0x00030000 /* address extension bits */ ++#define D64_RC_AE_SHIFT 16 ++#define D64_RC_BL_MASK 0x001C0000 /* BurstLen bits */ ++#define D64_RC_BL_SHIFT 18 ++#define D64_RC_PC_MASK 0x00E00000 /* Prefetch control */ ++#define D64_RC_PC_SHIFT 21 ++#define D64_RC_PT_MASK 0x03000000 /* Prefetch threshold */ ++#define D64_RC_PT_SHIFT 24 ++ ++/* flags for dma controller */ ++#define DMA_CTRL_PEN (1 << 0) /* partity enable */ ++#define DMA_CTRL_ROC (1 << 1) /* rx overflow continue */ ++#define DMA_CTRL_RXMULTI (1 << 2) /* allow rx scatter to multiple descriptors */ ++#define DMA_CTRL_UNFRAMED (1 << 3) /* Unframed Rx/Tx data */ ++#define DMA_CTRL_USB_BOUNDRY4KB_WAR (1 << 4) ++#define DMA_CTRL_DMA_AVOIDANCE_WAR (1 << 5) /* DMA avoidance WAR for 4331 */ ++#define DMA_CTRL_RXSINGLE (1 << 6) /* always single buffer */ ++ ++/* receive descriptor table pointer */ ++#define D64_RP_LD_MASK 0x00001fff /* last valid descriptor */ ++ ++/* receive channel status */ ++#define D64_RS0_CD_MASK 0x00001fff /* current descriptor pointer */ ++#define D64_RS0_RS_MASK 0xf0000000 /* receive state */ ++#define D64_RS0_RS_SHIFT 28 ++#define D64_RS0_RS_DISABLED 0x00000000 /* disabled */ ++#define D64_RS0_RS_ACTIVE 0x10000000 /* active */ ++#define D64_RS0_RS_IDLE 0x20000000 /* idle wait */ ++#define D64_RS0_RS_STOPPED 0x30000000 /* stopped */ ++#define D64_RS0_RS_SUSP 0x40000000 /* suspend pending */ ++ ++#define D64_RS1_AD_MASK 0x0001ffff /* active descriptor */ ++#define D64_RS1_RE_MASK 0xf0000000 /* receive errors */ ++#define D64_RS1_RE_SHIFT 28 ++#define D64_RS1_RE_NOERR 0x00000000 /* no error */ ++#define D64_RS1_RE_DPO 0x10000000 /* descriptor protocol error */ ++#define D64_RS1_RE_DFU 0x20000000 /* data fifo overflow */ ++#define D64_RS1_RE_DTE 0x30000000 /* data transfer error */ ++#define D64_RS1_RE_DESRE 0x40000000 /* descriptor read error */ ++#define D64_RS1_RE_COREE 0x50000000 /* core error */ ++ ++/* fifoaddr */ ++#define D64_FA_OFF_MASK 0xffff /* offset */ ++#define D64_FA_SEL_MASK 0xf0000 /* select */ ++#define D64_FA_SEL_SHIFT 16 ++#define D64_FA_SEL_XDD 0x00000 /* transmit dma data */ ++#define D64_FA_SEL_XDP 0x10000 /* transmit dma pointers */ ++#define D64_FA_SEL_RDD 0x40000 /* receive dma data */ ++#define D64_FA_SEL_RDP 0x50000 /* receive dma pointers */ ++#define D64_FA_SEL_XFD 0x80000 /* transmit fifo data */ ++#define D64_FA_SEL_XFP 0x90000 /* transmit fifo pointers */ ++#define D64_FA_SEL_RFD 0xc0000 /* receive fifo data */ ++#define D64_FA_SEL_RFP 0xd0000 /* receive fifo pointers */ ++#define D64_FA_SEL_RSD 0xe0000 /* receive frame status data */ ++#define D64_FA_SEL_RSP 0xf0000 /* receive frame status pointers */ ++ ++/* descriptor control flags 1 */ ++#define D64_CTRL_COREFLAGS 0x0ff00000 /* core specific flags */ ++#define D64_CTRL1_EOT ((uint32)1 << 28) /* end of descriptor table */ ++#define D64_CTRL1_IOC ((uint32)1 << 29) /* interrupt on completion */ ++#define D64_CTRL1_EOF ((uint32)1 << 30) /* end of frame */ ++#define D64_CTRL1_SOF ((uint32)1 << 31) /* start of frame */ ++ ++/* descriptor control flags 2 */ ++#define D64_CTRL2_BC_MASK 0x00007fff /* buffer byte count. real data len must <= 16KB */ ++#define D64_CTRL2_AE 0x00030000 /* address extension bits */ ++#define D64_CTRL2_AE_SHIFT 16 ++#define D64_CTRL2_PARITY 0x00040000 /* parity bit */ ++ ++/* control flags in the range [27:20] are core-specific and not defined here */ ++#define D64_CTRL_CORE_MASK 0x0ff00000 ++ ++#define D64_RX_FRM_STS_LEN 0x0000ffff /* frame length mask */ ++#define D64_RX_FRM_STS_OVFL 0x00800000 /* RxOverFlow */ ++#define D64_RX_FRM_STS_DSCRCNT 0x0f000000 /* no. of descriptors used - 1, d11corerev >= 22 */ ++#define D64_RX_FRM_STS_DATATYPE 0xf0000000 /* core-dependent data type */ ++ ++/* receive frame status */ ++typedef volatile struct { ++ uint16 len; ++ uint16 flags; ++} dma_rxh_t; ++ ++#endif /* _sbhnddma_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/sbsocram.h b/drivers/net/ethernet/broadcom/gmac/src/include/sbsocram.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/sbsocram.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/sbsocram.h 2017-11-09 17:53:44.007303000 +0800 +@@ -0,0 +1,193 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * BCM47XX Sonics SiliconBackplane embedded ram core ++ * ++ * $Id: sbsocram.h 271781 2011-07-13 20:00:06Z $ ++ */ ++ ++#ifndef _SBSOCRAM_H ++#define _SBSOCRAM_H ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif /* PAD */ ++ ++/* Memcsocram core registers */ ++typedef volatile struct sbsocramregs { ++ uint32 coreinfo; ++ uint32 bwalloc; ++ uint32 extracoreinfo; ++ uint32 biststat; ++ uint32 bankidx; ++ uint32 standbyctrl; ++ ++ uint32 errlogstatus; /* rev 6 */ ++ uint32 errlogaddr; /* rev 6 */ ++ /* used for patching rev 3 & 5 */ ++ uint32 cambankidx; ++ uint32 cambankstandbyctrl; ++ uint32 cambankpatchctrl; ++ uint32 cambankpatchtblbaseaddr; ++ uint32 cambankcmdreg; ++ uint32 cambankdatareg; ++ uint32 cambankmaskreg; ++ uint32 PAD[1]; ++ uint32 bankinfo; /* corev 8 */ ++ uint32 PAD[15]; ++ uint32 extmemconfig; ++ uint32 extmemparitycsr; ++ uint32 extmemparityerrdata; ++ uint32 extmemparityerrcnt; ++ uint32 extmemwrctrlandsize; ++ uint32 PAD[84]; ++ uint32 workaround; ++ uint32 pwrctl; /* corerev >= 2 */ ++ uint32 PAD[133]; ++ uint32 sr_control; /* corerev >= 15 */ ++ uint32 sr_status; /* corerev >= 15 */ ++ uint32 sr_address; /* corerev >= 15 */ ++ uint32 sr_data; /* corerev >= 15 */ ++} sbsocramregs_t; ++ ++#endif /* _LANGUAGE_ASSEMBLY */ ++ ++/* Register offsets */ ++#define SR_COREINFO 0x00 ++#define SR_BWALLOC 0x04 ++#define SR_BISTSTAT 0x0c ++#define SR_BANKINDEX 0x10 ++#define SR_BANKSTBYCTL 0x14 ++#define SR_PWRCTL 0x1e8 ++ ++/* Coreinfo register */ ++#define SRCI_PT_MASK 0x00070000 /* corerev >= 6; port type[18:16] */ ++#define SRCI_PT_SHIFT 16 ++/* port types : SRCI_PT__ */ ++#define SRCI_PT_OCP_OCP 0 ++#define SRCI_PT_AXI_OCP 1 ++#define SRCI_PT_ARM7AHB_OCP 2 ++#define SRCI_PT_CM3AHB_OCP 3 ++#define SRCI_PT_AXI_AXI 4 ++#define SRCI_PT_AHB_AXI 5 ++/* corerev >= 3 */ ++#define SRCI_LSS_MASK 0x00f00000 ++#define SRCI_LSS_SHIFT 20 ++#define SRCI_LRS_MASK 0x0f000000 ++#define SRCI_LRS_SHIFT 24 ++ ++/* In corerev 0, the memory size is 2 to the power of the ++ * base plus 16 plus to the contents of the memsize field plus 1. ++ */ ++#define SRCI_MS0_MASK 0xf ++#define SR_MS0_BASE 16 ++ ++/* ++ * In corerev 1 the bank size is 2 ^ the bank size field plus 14, ++ * the memory size is number of banks times bank size. ++ * The same applies to rom size. ++ */ ++#define SRCI_ROMNB_MASK 0xf000 ++#define SRCI_ROMNB_SHIFT 12 ++#define SRCI_ROMBSZ_MASK 0xf00 ++#define SRCI_ROMBSZ_SHIFT 8 ++#define SRCI_SRNB_MASK 0xf0 ++#define SRCI_SRNB_SHIFT 4 ++#define SRCI_SRBSZ_MASK 0xf ++#define SRCI_SRBSZ_SHIFT 0 ++ ++#define SR_BSZ_BASE 14 ++ ++/* Standby control register */ ++#define SRSC_SBYOVR_MASK 0x80000000 ++#define SRSC_SBYOVR_SHIFT 31 ++#define SRSC_SBYOVRVAL_MASK 0x60000000 ++#define SRSC_SBYOVRVAL_SHIFT 29 ++#define SRSC_SBYEN_MASK 0x01000000 /* rev >= 3 */ ++#define SRSC_SBYEN_SHIFT 24 ++ ++/* Power control register */ ++#define SRPC_PMU_STBYDIS_MASK 0x00000010 /* rev >= 3 */ ++#define SRPC_PMU_STBYDIS_SHIFT 4 ++#define SRPC_STBYOVRVAL_MASK 0x00000008 ++#define SRPC_STBYOVRVAL_SHIFT 3 ++#define SRPC_STBYOVR_MASK 0x00000007 ++#define SRPC_STBYOVR_SHIFT 0 ++ ++/* Extra core capability register */ ++#define SRECC_NUM_BANKS_MASK 0x000000F0 ++#define SRECC_NUM_BANKS_SHIFT 4 ++#define SRECC_BANKSIZE_MASK 0x0000000F ++#define SRECC_BANKSIZE_SHIFT 0 ++ ++#define SRECC_BANKSIZE(value) (1 << (value)) ++ ++/* CAM bank patch control */ ++#define SRCBPC_PATCHENABLE 0x80000000 ++ ++#define SRP_ADDRESS 0x0001FFFC ++#define SRP_VALID 0x8000 ++ ++/* CAM bank command reg */ ++#define SRCMD_WRITE 0x00020000 ++#define SRCMD_READ 0x00010000 ++#define SRCMD_DONE 0x80000000 ++ ++#define SRCMD_DONE_DLY 1000 ++ ++/* bankidx and bankinfo reg defines corerev >= 8 */ ++#define SOCRAM_BANKINFO_SZMASK 0x7f ++#define SOCRAM_BANKIDX_ROM_MASK 0x100 ++ ++#define SOCRAM_BANKIDX_MEMTYPE_SHIFT 8 ++/* socram bankinfo memtype */ ++#define SOCRAM_MEMTYPE_RAM 0 ++#define SOCRAM_MEMTYPE_R0M 1 ++#define SOCRAM_MEMTYPE_DEVRAM 2 ++ ++#define SOCRAM_BANKINFO_REG 0x40 ++#define SOCRAM_BANKIDX_REG 0x10 ++#define SOCRAM_BANKINFO_STDBY_MASK 0x400 ++#define SOCRAM_BANKINFO_STDBY_TIMER 0x800 ++ ++/* bankinfo rev >= 10 */ ++#define SOCRAM_BANKINFO_DEVRAMSEL_SHIFT 13 ++#define SOCRAM_BANKINFO_DEVRAMSEL_MASK 0x2000 ++#define SOCRAM_BANKINFO_DEVRAMPRO_SHIFT 14 ++#define SOCRAM_BANKINFO_DEVRAMPRO_MASK 0x4000 ++#define SOCRAM_BANKINFO_SLPSUPP_SHIFT 15 ++#define SOCRAM_BANKINFO_SLPSUPP_MASK 0x8000 ++#define SOCRAM_BANKINFO_RETNTRAM_SHIFT 16 ++#define SOCRAM_BANKINFO_RETNTRAM_MASK 0x00010000 ++#define SOCRAM_BANKINFO_PDASZ_SHIFT 17 ++#define SOCRAM_BANKINFO_PDASZ_MASK 0x003E0000 ++#define SOCRAM_BANKINFO_DEVRAMREMAP_SHIFT 24 ++#define SOCRAM_BANKINFO_DEVRAMREMAP_MASK 0x01000000 ++ ++/* extracoreinfo register */ ++#define SOCRAM_DEVRAMBANK_MASK 0xF000 ++#define SOCRAM_DEVRAMBANK_SHIFT 12 ++ ++/* bank info to calculate bank size */ ++#define SOCRAM_BANKINFO_SZBASE 8192 ++#define SOCRAM_BANKSIZE_SHIFT 13 /* SOCRAM_BANKINFO_SZBASE */ ++ ++ ++#endif /* _SBSOCRAM_H */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/sgmiiplus2_serdes.h b/drivers/net/ethernet/broadcom/gmac/src/include/sgmiiplus2_serdes.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/sgmiiplus2_serdes.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/sgmiiplus2_serdes.h 2017-11-09 17:53:44.008297000 +0800 +@@ -0,0 +1,28 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * These routines provide access to the serdes ++ * ++ */ ++ ++#ifndef _SGMIIPLUS2_SERDES_H_ ++#define _SGMIIPLUS2_SERDES_H_ ++ ++#include ++ ++extern void sgmiiplus2_serdes_reset(uint eth_num, uint phyaddr); ++extern int sgmiiplus2_serdes_init(uint eth_num, uint phyaddr); ++ ++#endif /* _SGMIIPLUS2_SERDES_H_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/siutils.h b/drivers/net/ethernet/broadcom/gmac/src/include/siutils.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/siutils.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/siutils.h 2017-11-09 17:53:44.009295000 +0800 +@@ -0,0 +1,243 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Misc utility routines for accessing the SOC Interconnects ++ * of Broadcom HNBU chips. ++ * ++ * $Id: siutils.h 323456 2012-03-24 07:17:39Z $ ++ */ ++ ++#ifndef _siutils_h_ ++#define _siutils_h_ ++ ++#if defined(WLC_HIGH) && !defined(WLC_LOW) ++#include "bcm_rpc.h" ++#endif ++/* ++ * Data structure to export all chip specific common variables ++ * public (read-only) portion of siutils handle returned by si_attach() ++ */ ++struct si_pub { ++ uint socitype; /* SOCI_SB, SOCI_AI */ ++ ++ uint bustype; /* SI_BUS, PCI_BUS */ ++ uint buscoretype; /* PCI_CORE_ID, PCIE_CORE_ID, PCMCIA_CORE_ID */ ++ uint buscorerev; /* buscore rev */ ++ uint buscoreidx; /* buscore index */ ++ int ccrev; /* chip common core rev */ ++ uint32 cccaps; /* chip common capabilities */ ++ uint32 cccaps_ext; /* chip common capabilities extension */ ++ int pmurev; /* pmu core rev */ ++ uint32 pmucaps; /* pmu capabilities */ ++ uint boardtype; /* board type */ ++ uint boardrev; /* board rev */ ++ uint boardvendor; /* board vendor */ ++ uint boardflags; /* board flags */ ++ uint boardflags2; /* board flags2 */ ++ uint chip; /* chip number */ ++ uint chiprev; /* chip revision */ ++ uint chippkg; /* chip package option */ ++ uint32 chipst; /* chip status */ ++ bool issim; /* chip is in simulation or emulation */ ++ uint socirev; /* SOC interconnect rev */ ++ bool pci_pr32414; ++ spinlock_t sih_lock; ++ ++#if defined(WLC_HIGH) && !defined(WLC_LOW) ++ rpc_info_t *rpc; ++#endif ++}; ++ ++/* for HIGH_ONLY driver, the si_t must be writable to allow states sync from BMAC to HIGH driver ++ * for monolithic driver, it is readonly to prevent accident change ++ */ ++#if defined(WLC_HIGH) && !defined(WLC_LOW) ++typedef struct si_pub si_t; ++#else ++typedef const struct si_pub si_t; ++#endif ++ ++#ifdef ATE_BUILD ++typedef struct _ate_params { ++ void* wl; ++ uint8 gpio_input; ++ uint8 gpio_output; ++ bool cmd_proceed; ++ uint16 cmd_idx; ++ bool ate_cmd_done; ++} ate_params_t; ++#endif /* ATE_BUILD */ ++ ++/* ++ * Many of the routines below take an 'sih' handle as their first arg. ++ * Allocate this by calling si_attach(). Free it by calling si_detach(). ++ * At any one time, the sih is logically focused on one particular si core ++ * (the "current core"). ++ * Use si_setcore() or si_setcoreidx() to change the association to another core. ++ */ ++#define BADIDX (SI_MAXCORES + 1) ++ ++/* clkctl xtal what flags */ ++#define XTAL 0x1 /* primary crystal oscillator (2050) */ ++#define PLL 0x2 /* main chip pll */ ++ ++/* clkctl clk mode */ ++#define CLK_FAST 0 /* force fast (pll) clock */ ++#define CLK_DYNAMIC 2 /* enable dynamic clock control */ ++ ++/* GPIO usage priorities */ ++#define GPIO_DRV_PRIORITY 0 /* Driver */ ++#define GPIO_APP_PRIORITY 1 /* Application */ ++#define GPIO_HI_PRIORITY 2 /* Highest priority. Ignore GPIO reservation */ ++ ++/* GPIO pull up/down */ ++#define GPIO_PULLUP 0 ++#define GPIO_PULLDN 1 ++ ++/* GPIO event regtype */ ++#define GPIO_REGEVT 0 /* GPIO register event */ ++#define GPIO_REGEVT_INTMSK 1 /* GPIO register event int mask */ ++#define GPIO_REGEVT_INTPOL 2 /* GPIO register event int polarity */ ++ ++/* device path */ ++#define SI_DEVPATH_BUFSZ 16 /* min buffer size in bytes */ ++ ++/* SI routine enumeration: to be used by update function with multiple hooks */ ++#define SI_DOATTACH 1 ++#define SI_PCIDOWN 2 ++#define SI_PCIUP 3 ++ ++#if defined(BCMQT) ++#define ISSIM_ENAB(sih) ((sih)->issim) ++#else ++#define ISSIM_ENAB(sih) 0 ++#endif ++ ++/* PMU clock/power control */ ++#if defined(BCMPMUCTL) ++#define PMUCTL_ENAB(sih) (BCMPMUCTL) ++#else ++#define PMUCTL_ENAB(sih) ((sih)->cccaps & CC_CAP_PMU) ++#endif ++ ++/* chipcommon clock/power control (exclusive with PMU's) */ ++#if defined(BCMPMUCTL) && BCMPMUCTL ++#define CCCTL_ENAB(sih) (0) ++#define CCPLL_ENAB(sih) (0) ++#else ++#define CCCTL_ENAB(sih) ((sih)->cccaps & CC_CAP_PWR_CTL) ++#define CCPLL_ENAB(sih) ((sih)->cccaps & CC_CAP_PLL_MASK) ++#endif ++ ++typedef void (*gpio_handler_t)(uint32 stat, void *arg); ++/* External BT Coex enable mask */ ++#define CC_BTCOEX_EN_MASK 0x01 ++/* External PA enable mask */ ++#define GPIO_CTRL_EPA_EN_MASK 0x40 ++/* WL/BT control enable mask */ ++#define GPIO_CTRL_5_6_EN_MASK 0x60 ++#define GPIO_CTRL_7_6_EN_MASK 0xC0 ++#define GPIO_OUT_7_EN_MASK 0x80 ++ ++ ++/* === exported functions === */ ++extern si_t *si_attach(uint pcidev, osl_t *osh, void *regs, uint bustype, ++ void *sdh, char **vars, uint *varsz); ++extern void si_detach(si_t *sih); ++ ++extern uint si_corelist(si_t *sih, uint coreid[]); ++extern uint si_coreid(si_t *sih); ++extern uint si_flag(si_t *sih); ++extern uint si_intflag(si_t *sih); ++extern uint si_coreidx(si_t *sih); ++extern uint si_coreunit(si_t *sih); ++extern uint si_corevendor(si_t *sih); ++extern uint si_corerev(si_t *sih); ++extern void *si_osh(si_t *sih); ++extern void si_setosh(si_t *sih, osl_t *osh); ++extern uint si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val); ++extern void *si_coreregs(si_t *sih); ++extern uint si_wrapperreg(si_t *sih, uint32 offset, uint32 mask, uint32 val); ++extern uint32 si_core_cflags(si_t *sih, uint32 mask, uint32 val); ++extern void si_core_cflags_wo(si_t *sih, uint32 mask, uint32 val); ++extern uint32 si_core_sflags(si_t *sih, uint32 mask, uint32 val); ++#ifdef WLC_HIGH_ONLY ++extern bool wlc_bmac_iscoreup(si_t *sih); ++#define si_iscoreup(sih) wlc_bmac_iscoreup(sih) ++#else ++extern bool si_iscoreup(si_t *sih); ++#endif /* __CONFIG_USBAP__ */ ++extern uint si_findcoreidx(si_t *sih, uint coreid, uint coreunit); ++extern void *si_setcoreidx(si_t *sih, uint coreidx); ++extern void *si_setcore(si_t *sih, uint coreid, uint coreunit); ++extern void *si_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val); ++extern void si_restore_core(si_t *sih, uint coreid, uint intr_val); ++extern int si_numaddrspaces(si_t *sih); ++extern uint32 si_addrspace(si_t *sih, uint asidx); ++extern uint32 si_addrspacesize(si_t *sih, uint asidx); ++extern void si_coreaddrspaceX(si_t *sih, uint asidx, uint32 *addr, uint32 *size); ++extern int si_corebist(si_t *sih); ++extern void si_core_reset(si_t *sih, uint32 bits, uint32 resetbits); ++extern void si_core_disable(si_t *sih, uint32 bits); ++extern uint32 si_clock_rate(uint32 pll_type, uint32 n, uint32 m); ++extern uint32 si_clock(si_t *sih); ++extern void si_setint(si_t *sih, int siflag); ++extern bool si_backplane64(si_t *sih); ++extern void si_clkctl_init(si_t *sih); ++extern bool si_clkctl_cc(si_t *sih, uint mode); ++extern int si_clkctl_xtal(si_t *sih, uint what, bool on); ++ ++extern uint32 si_gpioouten(si_t *sih, uint32 mask, uint32 val, uint8 priority); ++extern uint32 si_gpioout(si_t *sih, uint32 mask, uint32 val, uint8 priority); ++ ++/* Wake-on-wireless-LAN (WOWL) */ ++extern bool si_pci_pmecap(si_t *sih); ++struct osl_info; ++extern bool si_pci_fastpmecap(struct osl_info *osh); ++ ++/* Fab-id information */ ++#define DEFAULT_FAB 0x0 /* Original/first fab used for this chip */ ++#define CSM_FAB7 0x1 /* CSM Fab7 chip */ ++#define TSMC_FAB12 0x2 /* TSMC Fab12/Fab14 chip */ ++#define SMIC_FAB4 0x3 /* SMIC Fab4 chip */ ++ ++/* ++ * Build device path. Path size must be >= SI_DEVPATH_BUFSZ. ++ * The returned path is NULL terminated and has trailing '/'. ++ * Return 0 on success, nonzero otherwise. ++ */ ++extern int si_devpath(si_t *sih, char *path, int size); ++/* Read variable with prepending the devpath to the name */ ++extern int si_getdevpathintvar(si_t *sih, const char *name); ++extern char *si_coded_devpathvar(si_t *sih, char *varname, int var_len, const char *name); ++ ++ ++extern void si_war42780_clkreq(si_t *sih, bool clkreq); ++extern void si_pcie_extendL1timer(si_t *sih, bool extend); ++ ++/* === debug routines === */ ++ ++#ifdef BCMDBG ++extern void si_view(si_t *sih, bool verbose); ++extern void si_viewall(si_t *sih, bool verbose); ++#endif ++ ++#if defined(BCMDBG) ++struct bcmstrbuf; ++extern void si_dumpregs(si_t *sih, struct bcmstrbuf *b); ++#endif ++ ++ ++#endif /* _siutils_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/trxhdr.h b/drivers/net/ethernet/broadcom/gmac/src/include/trxhdr.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/trxhdr.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/trxhdr.h 2017-11-09 17:53:44.010293000 +0800 +@@ -0,0 +1,86 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * TRX image file header format. ++ * ++ * $Id: trxhdr.h 314841 2012-02-14 18:28:33Z $ ++ */ ++ ++#ifndef _TRX_HDR_H ++#define _TRX_HDR_H ++ ++#include ++ ++#define TRX_MAGIC 0x30524448 /* "HDR0" */ ++#define TRX_MAX_LEN 0x3B0000 /* Max length */ ++#define TRX_NO_HEADER 1 /* Do not write TRX header */ ++#define TRX_GZ_FILES 0x2 /* Contains up to TRX_MAX_OFFSET individual gzip files */ ++#define TRX_EMBED_UCODE 0x8 /* Trx contains embedded ucode image */ ++#define TRX_ROMSIM_IMAGE 0x10 /* Trx contains ROM simulation image */ ++#define TRX_UNCOMP_IMAGE 0x20 /* Trx contains uncompressed rtecdc.bin image */ ++#define TRX_BOOTLOADER 0x40 /* the image is a bootloader */ ++ ++#define TRX_V1 1 ++#define TRX_V1_MAX_OFFSETS 3 /* V1: Max number of individual files */ ++ ++#ifndef BCMTRXV2 ++#define TRX_VERSION TRX_V1 /* Version 1 */ ++#define TRX_MAX_OFFSET TRX_V1_MAX_OFFSETS ++#endif ++ ++/* BMAC Host driver/application like bcmdl need to support both Ver 1 as well as ++ * Ver 2 of trx header. To make it generic, trx_header is structure is modified ++ * as below where size of "offsets" field will vary as per the TRX version. ++ * Currently, BMAC host driver and bcmdl are modified to support TRXV2 as well. ++ * To make sure, other applications like "dhdl" which are yet to be enhanced to support ++ * TRXV2 are not broken, new macro and structure defintion take effect only when BCMTRXV2 ++ * is defined. ++ */ ++struct trx_header { ++ uint32 magic; /* "HDR0" */ ++ uint32 len; /* Length of file including header */ ++ uint32 crc32; /* 32-bit CRC from flag_version to end of file */ ++ uint32 flag_version; /* 0:15 flags, 16:31 version */ ++#ifndef BCMTRXV2 ++ uint32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of header */ ++#else ++ uint32 offsets[1]; /* Offsets of partitions from start of header */ ++#endif ++}; ++ ++#ifdef BCMTRXV2 ++#define TRX_VERSION TRX_V2 /* Version 2 */ ++#define TRX_MAX_OFFSET TRX_V2_MAX_OFFSETS ++ ++#define TRX_V2 2 ++/* V2: Max number of individual files ++ * To support SDR signature + Config data region ++ */ ++#define TRX_V2_MAX_OFFSETS 5 ++#define SIZEOF_TRXHDR_V1 (sizeof(struct trx_header)+(TRX_V1_MAX_OFFSETS-1)*sizeof(uint32)) ++#define SIZEOF_TRXHDR_V2 (sizeof(struct trx_header)+(TRX_V2_MAX_OFFSETS-1)*sizeof(uint32)) ++#define TRX_VER(trx) (trx->flag_version>>16) ++#define ISTRX_V1(trx) (TRX_VER(trx) == TRX_V1) ++#define ISTRX_V2(trx) (TRX_VER(trx) == TRX_V2) ++/* For V2, return size of V2 size: others, return V1 size */ ++#define SIZEOF_TRX(trx) (ISTRX_V2(trx) ? SIZEOF_TRXHDR_V2: SIZEOF_TRXHDR_V1) ++#else ++#define SIZEOF_TRX(trx) (sizeof(struct trx_header)) ++#endif /* BCMTRXV2 */ ++ ++/* Compatibility */ ++typedef struct trx_header TRXHDR, *PTRXHDR; ++ ++#endif /* _TRX_HDR_H */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/typedefs.h b/drivers/net/ethernet/broadcom/gmac/src/include/typedefs.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/typedefs.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/typedefs.h 2017-11-09 17:53:44.011290000 +0800 +@@ -0,0 +1,447 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * $Id: typedefs.h 286783 2011-09-29 06:18:57Z $ ++ */ ++ ++#ifndef _TYPEDEFS_H_ ++#define _TYPEDEFS_H_ ++ ++#ifdef SITE_TYPEDEFS ++ ++/* ++ * Define SITE_TYPEDEFS in the compile to include a site-specific ++ * typedef file "site_typedefs.h". ++ * ++ * If SITE_TYPEDEFS is not defined, then the code section below makes ++ * inferences about the compile environment based on defined symbols and ++ * possibly compiler pragmas. ++ * ++ * Following these two sections is the Default Typedefs section. ++ * This section is only processed if USE_TYPEDEF_DEFAULTS is ++ * defined. This section has a default set of typedefs and a few ++ * preprocessor symbols (TRUE, FALSE, NULL, ...). ++ */ ++ ++#include "site_typedefs.h" ++ ++#else ++ ++/* ++ * Infer the compile environment based on preprocessor symbols and pragmas. ++ * Override type definitions as needed, and include configuration-dependent ++ * header files to define types. ++ */ ++ ++#ifdef __cplusplus ++ ++#define TYPEDEF_BOOL ++#ifndef FALSE ++#define FALSE false ++#endif ++#ifndef TRUE ++#define TRUE true ++#endif ++ ++#else /* ! __cplusplus */ ++ ++#if defined(_WIN32) ++ ++#define TYPEDEF_BOOL ++typedef unsigned char bool; /* consistent w/BOOL */ ++ ++#endif /* _WIN32 */ ++ ++#endif /* ! __cplusplus */ ++ ++#if defined(_WIN64) && !defined(EFI) ++/* use the Windows ULONG_PTR type when compiling for 64 bit */ ++#include ++#define TYPEDEF_UINTPTR ++typedef ULONG_PTR uintptr; ++#elif defined(__x86_64__) ++#define TYPEDEF_UINTPTR ++typedef unsigned long long int uintptr; ++#endif ++ ++ ++#if defined(_MINOSL_) ++#define _NEED_SIZE_T_ ++#endif ++ ++#if defined(EFI) && !defined(_WIN64) ++#define _NEED_SIZE_T_ ++#endif ++ ++#if defined(TARGETOS_nucleus) ++/* for 'size_t' type */ ++#include ++ ++/* float_t types conflict with the same typedefs from the standard ANSI-C ++** math.h header file. Don't re-typedef them here. ++*/ ++#define TYPEDEF_FLOAT_T ++#endif /* TARGETOS_nucleus */ ++ ++#if defined(_NEED_SIZE_T_) ++typedef long unsigned int size_t; ++#endif ++ ++#ifdef _MSC_VER /* Microsoft C */ ++#define TYPEDEF_INT64 ++#define TYPEDEF_UINT64 ++typedef signed __int64 int64; ++typedef unsigned __int64 uint64; ++#endif ++ ++#if defined(MACOSX) ++#define TYPEDEF_BOOL ++#endif ++ ++#if defined(__NetBSD__) ++#define TYPEDEF_BOOL ++#ifndef _KERNEL ++#include ++#endif ++#define TYPEDEF_UINT ++#define TYPEDEF_USHORT ++#define TYPEDEF_ULONG ++#endif /* defined(__NetBSD__) */ ++ ++#if defined(__sparc__) ++#define TYPEDEF_ULONG ++#endif ++ ++ ++#ifdef linux ++/* ++ * If this is either a Linux hybrid build or the per-port code of a hybrid build ++ * then use the Linux header files to get some of the typedefs. Otherwise, define ++ * them entirely in this file. We can't always define the types because we get ++ * a duplicate typedef error; there is no way to "undefine" a typedef. ++ * We know when it's per-port code because each file defines LINUX_PORT at the top. ++ */ ++#if !defined(LINUX_HYBRID) || defined(LINUX_PORT) ++#define TYPEDEF_UINT ++#ifndef TARGETENV_android ++#define TYPEDEF_USHORT ++#define TYPEDEF_ULONG ++#endif /* TARGETENV_android */ ++#ifdef __KERNEL__ ++#include ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)) ++#define TYPEDEF_BOOL ++#endif /* >= 2.6.19 */ ++/* special detection for 2.6.18-128.7.1.0.1.el5 */ ++#if (LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 18)) ++#include ++#ifdef noinline_for_stack ++#define TYPEDEF_BOOL ++#endif ++#endif /* == 2.6.18 */ ++#endif /* __KERNEL__ */ ++#endif /* !defined(LINUX_HYBRID) || defined(LINUX_PORT) */ ++#endif /* linux */ ++ ++#if defined(__ECOS) ++#define TYPEDEF_UCHAR ++#define TYPEDEF_UINT ++#define TYPEDEF_USHORT ++#define TYPEDEF_ULONG ++#define TYPEDEF_BOOL ++#endif ++ ++#if !defined(linux) && !defined(_WIN32) && !defined(_CFE_) && !defined(_MINOSL_) && \ ++ !defined(__DJGPP__) && !defined(__ECOS) && !defined(__BOB__) && \ ++ !defined(TARGETOS_nucleus) && !defined(EFI) && !defined(__FreeBSD__) ++#define TYPEDEF_UINT ++#define TYPEDEF_USHORT ++#endif ++ ++ ++/* Do not support the (u)int64 types with strict ansi for GNU C */ ++#if defined(__GNUC__) && defined(__STRICT_ANSI__) ++#define TYPEDEF_INT64 ++#define TYPEDEF_UINT64 ++#endif ++ ++/* ICL accepts unsigned 64 bit type only, and complains in ANSI mode ++ * for signed or unsigned ++ */ ++#if defined(__ICL) ++ ++#define TYPEDEF_INT64 ++ ++#if defined(__STDC__) ++#define TYPEDEF_UINT64 ++#endif ++ ++#endif /* __ICL */ ++ ++#if !defined(_WIN32) && !defined(_CFE_) && !defined(_MINOSL_) && !defined(__DJGPP__) && \ ++ !defined(__BOB__) && !defined(TARGETOS_nucleus) && !defined(EFI) ++ ++/* pick up ushort & uint from standard types.h */ ++#if defined(linux) && defined(__KERNEL__) ++ ++/* See note above */ ++#if !defined(LINUX_HYBRID) || defined(LINUX_PORT) ++#ifdef USER_MODE ++#include ++#else ++#include /* sys/types.h and linux/types.h are oil and water */ ++#endif /* USER_MODE */ ++#endif /* !defined(LINUX_HYBRID) || defined(LINUX_PORT) */ ++ ++#else ++ ++#if defined(__ECOS) ++#include ++#include ++#include ++#endif ++ ++#include ++ ++#endif /* linux && __KERNEL__ */ ++ ++#endif ++ ++#ifdef CONFIG_CPU_BIG_ENDIAN ++#define IL_BIGENDIAN ++#else ++#ifdef IL_BIGENDIAN ++#error "IL_BIGENDIAN was defined for a little-endian compile" ++#endif ++#endif /* CONFIG_CPU_BIG_ENDIAN */ ++ ++#if defined(MACOSX) ++ ++#ifdef __BIG_ENDIAN__ ++#define IL_BIGENDIAN ++#else ++#ifdef IL_BIGENDIAN ++#error "IL_BIGENDIAN was defined for a little-endian compile" ++#endif ++#endif /* __BIG_ENDIAN__ */ ++ ++#if !defined(__cplusplus) ++ ++#if defined(__i386__) ++typedef unsigned char bool; ++#else ++typedef unsigned int bool; ++#endif ++#define TYPE_BOOL 1 ++enum { ++ false = 0, ++ true = 1 ++}; ++ ++#if defined(KERNEL) ++#include ++#endif /* KERNEL */ ++ ++#endif /* __cplusplus */ ++ ++#endif /* MACOSX */ ++ ++ ++/* use the default typedefs in the next section of this file */ ++#define USE_TYPEDEF_DEFAULTS ++ ++#endif /* SITE_TYPEDEFS */ ++ ++ ++/* ++ * Default Typedefs ++ */ ++ ++#ifdef USE_TYPEDEF_DEFAULTS ++#undef USE_TYPEDEF_DEFAULTS ++ ++#ifndef TYPEDEF_BOOL ++typedef /* @abstract@ */ unsigned char bool; ++#endif ++ ++/* define uchar, ushort, uint, ulong */ ++ ++#ifndef TYPEDEF_UCHAR ++typedef unsigned char uchar; ++#endif ++ ++#ifndef TYPEDEF_USHORT ++typedef unsigned short ushort; ++#endif ++ ++#ifndef TYPEDEF_UINT ++typedef unsigned int uint; ++#endif ++ ++#ifndef TYPEDEF_ULONG ++typedef unsigned long ulong; ++#endif ++ ++/* define [u]int8/16/32/64, uintptr */ ++ ++#ifndef TYPEDEF_UINT8 ++typedef unsigned char uint8; ++#endif ++ ++#ifndef TYPEDEF_UINT16 ++typedef unsigned short uint16; ++#endif ++ ++#ifndef TYPEDEF_UINT32 ++typedef unsigned int uint32; ++#endif ++ ++#ifndef TYPEDEF_UINT64 ++typedef unsigned long long uint64; ++#endif ++ ++#ifndef TYPEDEF_UINTPTR ++typedef unsigned int uintptr; ++#endif ++ ++#ifndef TYPEDEF_INT8 ++typedef signed char int8; ++#endif ++ ++#ifndef TYPEDEF_INT16 ++typedef signed short int16; ++#endif ++ ++#ifndef TYPEDEF_INT32 ++typedef signed int int32; ++#endif ++ ++#ifndef TYPEDEF_INT64 ++typedef signed long long int64; ++#endif ++ ++/* define float32/64, float_t */ ++ ++#ifndef TYPEDEF_FLOAT32 ++typedef float float32; ++#endif ++ ++#ifndef TYPEDEF_FLOAT64 ++typedef double float64; ++#endif ++ ++/* ++ * abstracted floating point type allows for compile time selection of ++ * single or double precision arithmetic. Compiling with -DFLOAT32 ++ * selects single precision; the default is double precision. ++ */ ++ ++#ifndef TYPEDEF_FLOAT_T ++ ++#if defined(FLOAT32) ++typedef float32 float_t; ++#else /* default to double precision floating point */ ++typedef float64 float_t; ++#endif ++ ++#endif /* TYPEDEF_FLOAT_T */ ++ ++/* define macro values */ ++ ++#ifndef FALSE ++#define FALSE 0 ++#endif ++ ++#ifndef TRUE ++#define TRUE 1 /* TRUE */ ++#endif ++ ++#ifndef NULL ++#define NULL 0 ++#endif ++ ++#ifndef OFF ++#define OFF 0 ++#endif ++ ++#ifndef ON ++#define ON 1 /* ON = 1 */ ++#endif ++ ++#define AUTO (-1) /* Auto = -1 */ ++ ++/* define PTRSZ, INLINE */ ++ ++#ifndef PTRSZ ++#define PTRSZ sizeof(char*) ++#endif ++ ++ ++/* Detect compiler type. */ ++#ifdef _MSC_VER ++ #define BWL_COMPILER_MICROSOFT ++#elif defined(__GNUC__) || defined(__lint) ++ #define BWL_COMPILER_GNU ++#elif defined(__CC_ARM) && __CC_ARM ++ #define BWL_COMPILER_ARMCC ++#else ++ #error "Unknown compiler!" ++#endif /* _MSC_VER */ ++ ++ ++#ifndef INLINE ++ #if defined(BWL_COMPILER_MICROSOFT) ++ #define INLINE __inline ++ #elif defined(BWL_COMPILER_GNU) ++ #define INLINE __inline__ ++ #elif defined(BWL_COMPILER_ARMCC) ++ #define INLINE __inline ++ #else ++ #define INLINE ++ #endif /* _MSC_VER */ ++#endif /* INLINE */ ++ ++#undef TYPEDEF_BOOL ++#undef TYPEDEF_UCHAR ++#undef TYPEDEF_USHORT ++#undef TYPEDEF_UINT ++#undef TYPEDEF_ULONG ++#undef TYPEDEF_UINT8 ++#undef TYPEDEF_UINT16 ++#undef TYPEDEF_UINT32 ++#undef TYPEDEF_UINT64 ++#undef TYPEDEF_UINTPTR ++#undef TYPEDEF_INT8 ++#undef TYPEDEF_INT16 ++#undef TYPEDEF_INT32 ++#undef TYPEDEF_INT64 ++#undef TYPEDEF_FLOAT32 ++#undef TYPEDEF_FLOAT64 ++#undef TYPEDEF_FLOAT_T ++ ++#endif /* USE_TYPEDEF_DEFAULTS */ ++ ++/* Suppress unused parameter warning */ ++#define UNUSED_PARAMETER(x) (void)(x) ++ ++/* Avoid warning for discarded const or volatile qualifier in special cases (-Wcast-qual) */ ++#define DISCARD_QUAL(ptr, type) ((type *)(uintptr)(ptr)) ++ ++/* ++ * Including the bcmdefs.h here, to make sure everyone including typedefs.h ++ * gets this automatically ++*/ ++#include ++#endif /* _TYPEDEFS_H_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/wlioctl.h b/drivers/net/ethernet/broadcom/gmac/src/include/wlioctl.h +--- a/drivers/net/ethernet/broadcom/gmac/src/include/wlioctl.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/include/wlioctl.h 2017-11-09 17:53:44.016288000 +0800 +@@ -0,0 +1,4877 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Custom OID/ioctl definitions for ++ * Broadcom 802.11abg Networking Device Driver ++ * ++ * Definitions subject to change without notice. ++ * ++ * $Id: wlioctl.h 324203 2012-03-28 09:55:17Z $ ++ */ ++ ++#ifndef _wlioctl_h_ ++#define _wlioctl_h_ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#ifdef __NetBSD__ ++/* NetBSD 2.0 does not have SIOCDEVPRIVATE. */ ++#define SIOCDEVPRIVATE _IOWR('i', 139, struct ifreq) ++#endif ++ ++#ifndef INTF_NAME_SIZ ++#define INTF_NAME_SIZ 16 ++#endif ++ ++/* Used to send ioctls over the transport pipe */ ++typedef struct remote_ioctl { ++ cdc_ioctl_t msg; ++ uint data_len; ++#ifndef OLYMPIC_RWL ++ char intf_name[INTF_NAME_SIZ]; ++#endif ++} rem_ioctl_t; ++#define REMOTE_SIZE sizeof(rem_ioctl_t) ++#ifdef EFI ++#define BCMWL_IOCTL_GUID \ ++ {0xB4910A35, 0x88C5, 0x4328, { 0x90, 0x08, 0x9F, 0xB2, 0x00, 0x00, 0x0, 0x0 } } ++#endif /* EFI */ ++ ++#define ACTION_FRAME_SIZE 1800 ++ ++typedef struct wl_action_frame { ++ struct ether_addr da; ++ uint16 len; ++ uint32 packetId; ++ uint8 data[ACTION_FRAME_SIZE]; ++} wl_action_frame_t; ++ ++#define WL_WIFI_ACTION_FRAME_SIZE sizeof(struct wl_action_frame) ++ ++typedef struct ssid_info ++{ ++ uint8 ssid_len; /* the length of SSID */ ++ uint8 ssid[32]; /* SSID string */ ++} ssid_info_t; ++ ++typedef struct wl_af_params { ++ uint32 channel; ++ int32 dwell_time; ++ struct ether_addr BSSID; ++ wl_action_frame_t action_frame; ++} wl_af_params_t; ++ ++#define WL_WIFI_AF_PARAMS_SIZE sizeof(struct wl_af_params) ++ ++#define MFP_TEST_FLAG_NORMAL 0 ++#define MFP_TEST_FLAG_ANY_KEY 1 ++typedef struct wl_sa_query { ++ uint32 flag; ++ uint8 action; ++ uint16 id; ++ struct ether_addr da; ++} wl_sa_query_t; ++ ++ ++/* require default structure packing */ ++#define BWL_DEFAULT_PACKING ++#include ++ ++ ++#ifndef LINUX_POSTMOGRIFY_REMOVAL ++/* Legacy structure to help keep backward compatible wl tool and tray app */ ++ ++#define LEGACY_WL_BSS_INFO_VERSION 107 /* older version of wl_bss_info struct */ ++ ++typedef struct wl_bss_info_107 { ++ uint32 version; /* version field */ ++ uint32 length; /* byte length of data in this record, ++ * starting at version and including IEs ++ */ ++ struct ether_addr BSSID; ++ uint16 beacon_period; /* units are Kusec */ ++ uint16 capability; /* Capability information */ ++ uint8 SSID_len; ++ uint8 SSID[32]; ++ struct { ++ uint count; /* # rates in this set */ ++ uint8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */ ++ } rateset; /* supported rates */ ++ uint8 channel; /* Channel no. */ ++ uint16 atim_window; /* units are Kusec */ ++ uint8 dtim_period; /* DTIM period */ ++ int16 RSSI; /* receive signal strength (in dBm) */ ++ int8 phy_noise; /* noise (in dBm) */ ++ uint32 ie_length; /* byte length of Information Elements */ ++ /* variable length Information Elements */ ++} wl_bss_info_107_t; ++#endif /* LINUX_POSTMOGRIFY_REMOVAL */ ++ ++/* ++ * Per-BSS information structure. ++ */ ++ ++#define LEGACY2_WL_BSS_INFO_VERSION 108 /* old version of wl_bss_info struct */ ++ ++/* BSS info structure ++ * Applications MUST CHECK ie_offset field and length field to access IEs and ++ * next bss_info structure in a vector (in wl_scan_results_t) ++ */ ++typedef struct wl_bss_info_108 { ++ uint32 version; /* version field */ ++ uint32 length; /* byte length of data in this record, ++ * starting at version and including IEs ++ */ ++ struct ether_addr BSSID; ++ uint16 beacon_period; /* units are Kusec */ ++ uint16 capability; /* Capability information */ ++ uint8 SSID_len; ++ uint8 SSID[32]; ++ struct { ++ uint count; /* # rates in this set */ ++ uint8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */ ++ } rateset; /* supported rates */ ++ chanspec_t chanspec; /* chanspec for bss */ ++ uint16 atim_window; /* units are Kusec */ ++ uint8 dtim_period; /* DTIM period */ ++ int16 RSSI; /* receive signal strength (in dBm) */ ++ int8 phy_noise; /* noise (in dBm) */ ++ ++ uint8 n_cap; /* BSS is 802.11N Capable */ ++ uint32 nbss_cap; /* 802.11N BSS Capabilities (based on HT_CAP_*) */ ++ uint8 ctl_ch; /* 802.11N BSS control channel number */ ++ uint32 reserved32[1]; /* Reserved for expansion of BSS properties */ ++ uint8 flags; /* flags */ ++ uint8 reserved[3]; /* Reserved for expansion of BSS properties */ ++ uint8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */ ++ ++ uint16 ie_offset; /* offset at which IEs start, from beginning */ ++ uint32 ie_length; /* byte length of Information Elements */ ++ /* Add new fields here */ ++ /* variable length Information Elements */ ++} wl_bss_info_108_t; ++ ++#define WL_BSS_INFO_VERSION 109 /* current version of wl_bss_info struct */ ++ ++/* BSS info structure ++ * Applications MUST CHECK ie_offset field and length field to access IEs and ++ * next bss_info structure in a vector (in wl_scan_results_t) ++ */ ++typedef struct wl_bss_info { ++ uint32 version; /* version field */ ++ uint32 length; /* byte length of data in this record, ++ * starting at version and including IEs ++ */ ++ struct ether_addr BSSID; ++ uint16 beacon_period; /* units are Kusec */ ++ uint16 capability; /* Capability information */ ++ uint8 SSID_len; ++ uint8 SSID[32]; ++ struct { ++ uint count; /* # rates in this set */ ++ uint8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */ ++ } rateset; /* supported rates */ ++ chanspec_t chanspec; /* chanspec for bss */ ++ uint16 atim_window; /* units are Kusec */ ++ uint8 dtim_period; /* DTIM period */ ++ int16 RSSI; /* receive signal strength (in dBm) */ ++ int8 phy_noise; /* noise (in dBm) */ ++ ++ uint8 n_cap; /* BSS is 802.11N Capable */ ++ uint32 nbss_cap; /* 802.11N BSS Capabilities (based on HT_CAP_*) */ ++ uint8 ctl_ch; /* 802.11N BSS control channel number */ ++ uint16 vht_rxmcsmap; /* VHT rx mcs map */ ++ uint16 vht_txmcsmap; /* VHT tx mcs map */ ++ uint8 flags; /* flags */ ++ uint8 vht_cap; /* BSS is vht capable */ ++ uint8 reserved[2]; /* Reserved for expansion of BSS properties */ ++ uint8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */ ++ ++ uint16 ie_offset; /* offset at which IEs start, from beginning */ ++ uint32 ie_length; /* byte length of Information Elements */ ++ int16 SNR; /* average SNR of during frame reception */ ++ /* Add new fields here */ ++ /* variable length Information Elements */ ++} wl_bss_info_t; ++ ++typedef struct wl_bsscfg { ++ uint32 wsec; ++ uint32 WPA_auth; ++ uint32 wsec_index; ++ uint32 associated; ++ uint32 BSS; ++ uint32 phytest_on; ++ struct ether_addr prev_BSSID; ++ struct ether_addr BSSID; ++} wl_bsscfg_t; ++ ++typedef struct wl_bss_config { ++ uint32 atim_window; ++ uint32 beacon_period; ++ uint32 chanspec; ++} wl_bss_config_t; ++ ++#define DLOAD_HANDLER_VER 1 /* Downloader version */ ++#define DLOAD_FLAG_VER_MASK 0xf000 /* Downloader version mask */ ++#define DLOAD_FLAG_VER_SHIFT 12 /* Downloader version shift */ ++ ++#define DL_CRC_NOT_INUSE 0x0001 ++ ++/* generic download types & flags */ ++enum { ++ DL_TYPE_UCODE = 1, ++ DL_TYPE_CLM = 2 ++}; ++ ++/* ucode type values */ ++enum { ++ UCODE_FW, ++ INIT_VALS, ++ BS_INIT_VALS ++}; ++ ++struct wl_dload_data { ++ uint16 flag; ++ uint16 dload_type; ++ uint32 len; ++ uint32 crc; ++ uint8 data[1]; ++}; ++typedef struct wl_dload_data wl_dload_data_t; ++ ++struct wl_ucode_info { ++ uint32 ucode_type; ++ uint32 num_chunks; ++ uint32 chunk_len; ++ uint32 chunk_num; ++ uint8 data_chunk[1]; ++}; ++typedef struct wl_ucode_info wl_ucode_info_t; ++ ++struct wl_clm_dload_info { ++ uint32 ds_id; ++ uint32 clm_total_len; ++ uint32 num_chunks; ++ uint32 chunk_len; ++ uint32 chunk_offset; ++ uint8 data_chunk[1]; ++}; ++typedef struct wl_clm_dload_info wl_clm_dload_info_t; ++ ++typedef struct wlc_ssid { ++ uint32 SSID_len; ++ uchar SSID[32]; ++} wlc_ssid_t; ++ ++#define MAX_PREFERRED_AP_NUM 5 ++typedef struct wlc_fastssidinfo { ++ uint32 SSID_channel[MAX_PREFERRED_AP_NUM]; ++ wlc_ssid_t SSID_info[MAX_PREFERRED_AP_NUM]; ++} wlc_fastssidinfo_t; ++ ++typedef BWL_PRE_PACKED_STRUCT struct wnm_url { ++ uint8 len; ++ uint8 data[1]; ++} BWL_POST_PACKED_STRUCT wnm_url_t; ++ ++#ifndef LINUX_POSTMOGRIFY_REMOVAL ++typedef struct chan_scandata { ++ uint8 txpower; ++ uint8 pad; ++ chanspec_t channel; /* Channel num, bw, ctrl_sb and band */ ++ uint32 channel_mintime; ++ uint32 channel_maxtime; ++} chan_scandata_t; ++ ++typedef enum wl_scan_type { ++ EXTDSCAN_FOREGROUND_SCAN, ++ EXTDSCAN_BACKGROUND_SCAN, ++ EXTDSCAN_FORCEDBACKGROUND_SCAN ++} wl_scan_type_t; ++ ++#define WLC_EXTDSCAN_MAX_SSID 5 ++ ++#define WL_BSS_FLAGS_FROM_BEACON 0x01 /* bss_info derived from beacon */ ++#define WL_BSS_FLAGS_FROM_CACHE 0x02 /* bss_info collected from cache */ ++#define WL_BSS_FLAGS_RSSI_ONCHANNEL 0x04 /* rssi info was received on channel (vs offchannel) */ ++ ++typedef struct wl_extdscan_params { ++ int8 nprobes; /* 0, passive, otherwise active */ ++ int8 split_scan; /* split scan */ ++ int8 band; /* band */ ++ int8 pad; ++ wlc_ssid_t ssid[WLC_EXTDSCAN_MAX_SSID]; /* ssid list */ ++ uint32 tx_rate; /* in 500ksec units */ ++ wl_scan_type_t scan_type; /* enum */ ++ int32 channel_num; ++ chan_scandata_t channel_list[1]; /* list of chandata structs */ ++} wl_extdscan_params_t; ++ ++#define WL_EXTDSCAN_PARAMS_FIXED_SIZE (sizeof(wl_extdscan_params_t) - sizeof(chan_scandata_t)) ++#endif /* LINUX_POSTMOGRIFY_REMOVAL */ ++ ++#define WL_BSSTYPE_INFRA 1 ++#define WL_BSSTYPE_INDEP 0 ++#define WL_BSSTYPE_ANY 2 ++ ++/* Bitmask for scan_type */ ++#define WL_SCANFLAGS_PASSIVE 0x01 /* force passive scan */ ++#define WL_SCANFLAGS_RESERVED 0x02 /* Reserved */ ++#define WL_SCANFLAGS_PROHIBITED 0x04 /* allow scanning prohibited channels */ ++ ++#define WL_SCAN_PARAMS_SSID_MAX 10 ++ ++typedef struct wl_scan_params { ++ wlc_ssid_t ssid; /* default: {0, ""} */ ++ struct ether_addr bssid; /* default: bcast */ ++ int8 bss_type; /* default: any, ++ * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT ++ */ ++ uint8 scan_type; /* flags, 0 use default */ ++ int32 nprobes; /* -1 use default, number of probes per channel */ ++ int32 active_time; /* -1 use default, dwell time per channel for ++ * active scanning ++ */ ++ int32 passive_time; /* -1 use default, dwell time per channel ++ * for passive scanning ++ */ ++ int32 home_time; /* -1 use default, dwell time for the home channel ++ * between channel scans ++ */ ++ int32 channel_num; /* count of channels and ssids that follow ++ * ++ * low half is count of channels in channel_list, 0 ++ * means default (use all available channels) ++ * ++ * high half is entries in wlc_ssid_t array that ++ * follows channel_list, aligned for int32 (4 bytes) ++ * meaning an odd channel count implies a 2-byte pad ++ * between end of channel_list and first ssid ++ * ++ * if ssid count is zero, single ssid in the fixed ++ * parameter portion is assumed, otherwise ssid in ++ * the fixed portion is ignored ++ */ ++ uint16 channel_list[1]; /* list of chanspecs */ ++} wl_scan_params_t; ++ ++/* size of wl_scan_params not including variable length array */ ++#define WL_SCAN_PARAMS_FIXED_SIZE 64 ++ ++/* masks for channel and ssid count */ ++#define WL_SCAN_PARAMS_COUNT_MASK 0x0000ffff ++#define WL_SCAN_PARAMS_NSSID_SHIFT 16 ++ ++#define WL_SCAN_ACTION_START 1 ++#define WL_SCAN_ACTION_CONTINUE 2 ++#define WL_SCAN_ACTION_ABORT 3 ++ ++#define ISCAN_REQ_VERSION 1 ++ ++/* incremental scan struct */ ++typedef struct wl_iscan_params { ++ uint32 version; ++ uint16 action; ++ uint16 scan_duration; ++ wl_scan_params_t params; ++} wl_iscan_params_t; ++ ++/* 3 fields + size of wl_scan_params, not including variable length array */ ++#define WL_ISCAN_PARAMS_FIXED_SIZE (OFFSETOF(wl_iscan_params_t, params) + sizeof(wlc_ssid_t)) ++ ++typedef struct wl_scan_results { ++ uint32 buflen; ++ uint32 version; ++ uint32 count; ++ wl_bss_info_t bss_info[1]; ++} wl_scan_results_t; ++ ++/* size of wl_scan_results not including variable length array */ ++#define WL_SCAN_RESULTS_FIXED_SIZE (sizeof(wl_scan_results_t) - sizeof(wl_bss_info_t)) ++ ++/* wl_iscan_results status values */ ++#define WL_SCAN_RESULTS_SUCCESS 0 ++#define WL_SCAN_RESULTS_PARTIAL 1 ++#define WL_SCAN_RESULTS_PENDING 2 ++#define WL_SCAN_RESULTS_ABORTED 3 ++#define WL_SCAN_RESULTS_NO_MEM 4 ++ ++/* Used in EXT_STA */ ++#define DNGL_RXCTXT_SIZE 45 ++ ++#if defined(SIMPLE_ISCAN) ++#define ISCAN_RETRY_CNT 5 ++#define ISCAN_STATE_IDLE 0 ++#define ISCAN_STATE_SCANING 1 ++#define ISCAN_STATE_PENDING 2 ++ ++/* the buf lengh can be WLC_IOCTL_MAXLEN (8K) to reduce iteration */ ++#define WLC_IW_ISCAN_MAXLEN 2048 ++typedef struct iscan_buf { ++ struct iscan_buf * next; ++ char iscan_buf[WLC_IW_ISCAN_MAXLEN]; ++} iscan_buf_t; ++#endif /* SIMPLE_ISCAN */ ++ ++#define ESCAN_REQ_VERSION 1 ++ ++typedef struct wl_escan_params { ++ uint32 version; ++ uint16 action; ++ uint16 sync_id; ++ wl_scan_params_t params; ++} wl_escan_params_t; ++ ++#define WL_ESCAN_PARAMS_FIXED_SIZE (OFFSETOF(wl_escan_params_t, params) + sizeof(wlc_ssid_t)) ++ ++typedef struct wl_escan_result { ++ uint32 buflen; ++ uint32 version; ++ uint16 sync_id; ++ uint16 bss_count; ++ wl_bss_info_t bss_info[1]; ++} wl_escan_result_t; ++ ++#define WL_ESCAN_RESULTS_FIXED_SIZE (sizeof(wl_escan_result_t) - sizeof(wl_bss_info_t)) ++ ++/* incremental scan results struct */ ++typedef struct wl_iscan_results { ++ uint32 status; ++ wl_scan_results_t results; ++} wl_iscan_results_t; ++ ++/* size of wl_iscan_results not including variable length array */ ++#define WL_ISCAN_RESULTS_FIXED_SIZE \ ++ (WL_SCAN_RESULTS_FIXED_SIZE + OFFSETOF(wl_iscan_results_t, results)) ++ ++typedef struct wl_probe_params { ++ wlc_ssid_t ssid; ++ struct ether_addr bssid; ++ struct ether_addr mac; ++} wl_probe_params_t; ++ ++#define WL_MAXRATES_IN_SET 16 /* max # of rates in a rateset */ ++typedef struct wl_rateset { ++ uint32 count; /* # rates in this set */ ++ uint8 rates[WL_MAXRATES_IN_SET]; /* rates in 500kbps units w/hi bit set if basic */ ++} wl_rateset_t; ++ ++typedef struct wl_rateset_args { ++ uint32 count; /* # rates in this set */ ++ uint8 rates[WL_MAXRATES_IN_SET]; /* rates in 500kbps units w/hi bit set if basic */ ++ uint8 mcs[MCSSET_LEN]; /* supported mcs index bit map */ ++} wl_rateset_args_t; ++ ++/* uint32 list */ ++typedef struct wl_uint32_list { ++ /* in - # of elements, out - # of entries */ ++ uint32 count; ++ /* variable length uint32 list */ ++ uint32 element[1]; ++} wl_uint32_list_t; ++ ++/* used for association with a specific BSSID and chanspec list */ ++typedef struct wl_assoc_params { ++ struct ether_addr bssid; /* 00:00:00:00:00:00: broadcast scan */ ++ int32 chanspec_num; /* 0: all available channels, ++ * otherwise count of chanspecs in chanspec_list ++ */ ++ chanspec_t chanspec_list[1]; /* list of chanspecs */ ++} wl_assoc_params_t; ++#define WL_ASSOC_PARAMS_FIXED_SIZE OFFSETOF(wl_assoc_params_t, chanspec_list) ++ ++/* used for reassociation/roam to a specific BSSID and channel */ ++typedef wl_assoc_params_t wl_reassoc_params_t; ++#define WL_REASSOC_PARAMS_FIXED_SIZE WL_ASSOC_PARAMS_FIXED_SIZE ++ ++/* used for association to a specific BSSID and channel */ ++typedef wl_assoc_params_t wl_join_assoc_params_t; ++#define WL_JOIN_ASSOC_PARAMS_FIXED_SIZE WL_ASSOC_PARAMS_FIXED_SIZE ++ ++/* used for join with or without a specific bssid and channel list */ ++typedef struct wl_join_params { ++ wlc_ssid_t ssid; ++ wl_assoc_params_t params; /* optional field, but it must include the fixed portion ++ * of the wl_assoc_params_t struct when it does present. ++ */ ++} wl_join_params_t; ++#define WL_JOIN_PARAMS_FIXED_SIZE (OFFSETOF(wl_join_params_t, params) + \ ++ WL_ASSOC_PARAMS_FIXED_SIZE) ++/* scan params for extended join */ ++typedef struct wl_join_scan_params { ++ uint8 scan_type; /* 0 use default, active or passive scan */ ++ int32 nprobes; /* -1 use default, number of probes per channel */ ++ int32 active_time; /* -1 use default, dwell time per channel for ++ * active scanning ++ */ ++ int32 passive_time; /* -1 use default, dwell time per channel ++ * for passive scanning ++ */ ++ int32 home_time; /* -1 use default, dwell time for the home channel ++ * between channel scans ++ */ ++} wl_join_scan_params_t; ++ ++/* extended join params */ ++typedef struct wl_extjoin_params { ++ wlc_ssid_t ssid; /* {0, ""}: wildcard scan */ ++ wl_join_scan_params_t scan; ++ wl_join_assoc_params_t assoc; /* optional field, but it must include the fixed portion ++ * of the wl_join_assoc_params_t struct when it does ++ * present. ++ */ ++} wl_extjoin_params_t; ++#define WL_EXTJOIN_PARAMS_FIXED_SIZE (OFFSETOF(wl_extjoin_params_t, assoc) + \ ++ WL_JOIN_ASSOC_PARAMS_FIXED_SIZE) ++ ++/* All builds use the new 11ac ratespec/chanspec */ ++#undef D11AC_IOTYPES ++#define D11AC_IOTYPES ++ ++#ifndef D11AC_IOTYPES ++ ++/* defines used by the nrate iovar */ ++#define NRATE_MCS_INUSE 0x00000080 /* MSC in use,indicates b0-6 holds an mcs */ ++#define NRATE_RATE_MASK 0x0000007f /* rate/mcs value */ ++#define NRATE_STF_MASK 0x0000ff00 /* stf mode mask: siso, cdd, stbc, sdm */ ++#define NRATE_STF_SHIFT 8 /* stf mode shift */ ++#define NRATE_OVERRIDE 0x80000000 /* bit indicates override both rate & mode */ ++#define NRATE_OVERRIDE_MCS_ONLY 0x40000000 /* bit indicate to override mcs only */ ++#define NRATE_SGI_MASK 0x00800000 /* sgi mode */ ++#define NRATE_SGI_SHIFT 23 /* sgi mode */ ++#define NRATE_LDPC_CODING 0x00400000 /* bit indicates adv coding in use */ ++#define NRATE_LDPC_SHIFT 22 /* ldpc shift */ ++ ++#define NRATE_STF_SISO 0 /* stf mode SISO */ ++#define NRATE_STF_CDD 1 /* stf mode CDD */ ++#define NRATE_STF_STBC 2 /* stf mode STBC */ ++#define NRATE_STF_SDM 3 /* stf mode SDM */ ++ ++#else /* D11AC_IOTYPES */ ++ ++/* WL_RSPEC defines for rate information */ ++#define WL_RSPEC_RATE_MASK 0x000000FF /* rate or HT MCS value */ ++#define WL_RSPEC_VHT_MCS_MASK 0x0000000F /* VHT MCS value */ ++#define WL_RSPEC_VHT_NSS_MASK 0x000000F0 /* VHT Nss value */ ++#define WL_RSPEC_VHT_NSS_SHIFT 4 /* VHT Nss value shift */ ++#define WL_RSPEC_TXEXP_MASK 0x00000300 ++#define WL_RSPEC_TXEXP_SHIFT 8 ++#define WL_RSPEC_BW_MASK 0x00070000 /* bandwidth mask */ ++#define WL_RSPEC_BW_SHIFT 16 /* bandwidth shift */ ++#define WL_RSPEC_STBC 0x00100000 /* STBC encoding, Nsts = 2 x Nss */ ++#define WL_RSPEC_LDPC 0x00400000 /* bit indicates adv coding in use */ ++#define WL_RSPEC_SGI 0x00800000 /* Short GI mode */ ++#define WL_RSPEC_ENCODING_MASK 0x03000000 /* Encoding of Rate/MCS field */ ++#define WL_RSPEC_OVERRIDE_RATE 0x40000000 /* bit indicate to override mcs only */ ++#define WL_RSPEC_OVERRIDE_MODE 0x80000000 /* bit indicates override both rate & mode */ ++ ++/* WL_RSPEC_ENCODING field defs */ ++#define WL_RSPEC_ENCODE_RATE 0x00000000 /* Legacy rate is stored in RSPEC_RATE_MASK */ ++#define WL_RSPEC_ENCODE_HT 0x01000000 /* HT MCS is stored in RSPEC_RATE_MASK */ ++#define WL_RSPEC_ENCODE_VHT 0x02000000 /* VHT MCS and Nss is stored in RSPEC_RATE_MASK */ ++ ++/* WL_RSPEC_BW field defs */ ++#define WL_RSPEC_BW_UNSPECIFIED 0 ++#define WL_RSPEC_BW_20MHZ 0x00010000 ++#define WL_RSPEC_BW_40MHZ 0x00020000 ++#define WL_RSPEC_BW_80MHZ 0x00030000 ++#define WL_RSPEC_BW_160MHZ 0x00040000 ++ ++/* Legacy defines for the nrate iovar */ ++#define OLD_NRATE_MCS_INUSE 0x00000080 /* MSC in use,indicates b0-6 holds an mcs */ ++#define OLD_NRATE_RATE_MASK 0x0000007f /* rate/mcs value */ ++#define OLD_NRATE_STF_MASK 0x0000ff00 /* stf mode mask: siso, cdd, stbc, sdm */ ++#define OLD_NRATE_STF_SHIFT 8 /* stf mode shift */ ++#define OLD_NRATE_OVERRIDE 0x80000000 /* bit indicates override both rate & mode */ ++#define OLD_NRATE_OVERRIDE_MCS_ONLY 0x40000000 /* bit indicate to override mcs only */ ++#define OLD_NRATE_SGI 0x00800000 /* sgi mode */ ++#define OLD_NRATE_LDPC_CODING 0x00400000 /* bit indicates adv coding in use */ ++ ++#define OLD_NRATE_STF_SISO 0 /* stf mode SISO */ ++#define OLD_NRATE_STF_CDD 1 /* stf mode CDD */ ++#define OLD_NRATE_STF_STBC 2 /* stf mode STBC */ ++#define OLD_NRATE_STF_SDM 3 /* stf mode SDM */ ++ ++#endif /* D11AC_IOTYPES */ ++ ++#define ANTENNA_NUM_1 1 /* total number of antennas to be used */ ++#define ANTENNA_NUM_2 2 ++#define ANTENNA_NUM_3 3 ++#define ANTENNA_NUM_4 4 ++ ++#define ANT_SELCFG_AUTO 0x80 /* bit indicates antenna sel AUTO */ ++#define ANT_SELCFG_MASK 0x33 /* antenna configuration mask */ ++#define ANT_SELCFG_MAX 4 /* max number of antenna configurations */ ++#define ANT_SELCFG_TX_UNICAST 0 /* unicast tx antenna configuration */ ++#define ANT_SELCFG_RX_UNICAST 1 /* unicast rx antenna configuration */ ++#define ANT_SELCFG_TX_DEF 2 /* default tx antenna configuration */ ++#define ANT_SELCFG_RX_DEF 3 /* default rx antenna configuration */ ++ ++#define MAX_STREAMS_SUPPORTED 4 /* max number of streams supported */ ++ ++typedef struct { ++ uint8 ant_config[ANT_SELCFG_MAX]; /* antenna configuration */ ++ uint8 num_antcfg; /* number of available antenna configurations */ ++} wlc_antselcfg_t; ++ ++#define HIGHEST_SINGLE_STREAM_MCS 7 /* MCS values greater than this enable multiple streams */ ++ ++#define MAX_CCA_CHANNELS 38 /* Max number of 20 Mhz wide channels */ ++#define MAX_CCA_SECS 60 /* CCA keeps this many seconds history */ ++ ++#define IBSS_MED 15 /* Mediom in-bss congestion percentage */ ++#define IBSS_HI 25 /* Hi in-bss congestion percentage */ ++#define OBSS_MED 12 ++#define OBSS_HI 25 ++#define INTERFER_MED 5 ++#define INTERFER_HI 10 ++ ++#define CCA_FLAG_2G_ONLY 0x01 /* Return a channel from 2.4 Ghz band */ ++#define CCA_FLAG_5G_ONLY 0x02 /* Return a channel from 2.4 Ghz band */ ++#define CCA_FLAG_IGNORE_DURATION 0x04 /* Ignore dwell time for each channel */ ++#define CCA_FLAGS_PREFER_1_6_11 0x10 ++#define CCA_FLAG_IGNORE_INTERFER 0x20 /* do not exlude channel based on interfer level */ ++ ++#define CCA_ERRNO_BAND 1 /* After filtering for band pref, no choices left */ ++#define CCA_ERRNO_DURATION 2 /* After filtering for duration, no choices left */ ++#define CCA_ERRNO_PREF_CHAN 3 /* After filtering for chan pref, no choices left */ ++#define CCA_ERRNO_INTERFER 4 /* After filtering for interference, no choices left */ ++#define CCA_ERRNO_TOO_FEW 5 /* Only 1 channel was input */ ++ ++typedef struct { ++ uint32 duration; /* millisecs spent sampling this channel */ ++ uint32 congest_ibss; /* millisecs in our bss (presumably this traffic will */ ++ /* move if cur bss moves channels) */ ++ uint32 congest_obss; /* traffic not in our bss */ ++ uint32 interference; /* millisecs detecting a non 802.11 interferer. */ ++ uint32 timestamp; /* second timestamp */ ++} cca_congest_t; ++ ++typedef struct { ++ chanspec_t chanspec; /* Which channel? */ ++ uint8 num_secs; /* How many secs worth of data */ ++ cca_congest_t secs[1]; /* Data */ ++} cca_congest_channel_req_t; ++ ++/* interference source detection and identification mode */ ++#define ITFR_MODE_DISABLE 0 /* disable feature */ ++#define ITFR_MODE_MANUAL_ENABLE 1 /* enable manual detection */ ++#define ITFR_MODE_AUTO_ENABLE 2 /* enable auto detection */ ++ ++/* interference sources */ ++enum interference_source { ++ ITFR_NONE = 0, /* interference */ ++ ITFR_PHONE, /* wireless phone */ ++ ITFR_VIDEO_CAMERA, /* wireless video camera */ ++ ITFR_MICROWAVE_OVEN, /* microwave oven */ ++ ITFR_BABY_MONITOR, /* wireless baby monitor */ ++ ITFR_BLUETOOTH, /* bluetooth */ ++ ITFR_VIDEO_CAMERA_OR_BABY_MONITOR, /* wireless camera or baby monitor */ ++ ITFR_BLUETOOTH_OR_BABY_MONITOR, /* bluetooth or baby monitor */ ++ ITFR_VIDEO_CAMERA_OR_PHONE, /* video camera or phone */ ++ ITFR_UNIDENTIFIED /* interference from unidentified source */ ++}; ++ ++/* structure for interference source report */ ++typedef struct { ++ uint32 flags; /* flags. bit definitions below */ ++ uint32 source; /* last detected interference source */ ++ uint32 timestamp; /* second timestamp on interferenced flag change */ ++} interference_source_rep_t; ++ ++/* bit definitions for flags in interference source report */ ++#define ITFR_INTERFERENCED 1 /* interference detected */ ++#define ITFR_HOME_CHANNEL 2 /* home channel has interference */ ++#define ITFR_NOISY_ENVIRONMENT 4 /* noisy environemnt so feature stopped */ ++ ++#define WLC_CNTRY_BUF_SZ 4 /* Country string is 3 bytes + NUL */ ++ ++typedef struct wl_country { ++ char country_abbrev[WLC_CNTRY_BUF_SZ]; /* nul-terminated country code used in ++ * the Country IE ++ */ ++ int32 rev; /* revision specifier for ccode ++ * on set, -1 indicates unspecified. ++ * on get, rev >= 0 ++ */ ++ char ccode[WLC_CNTRY_BUF_SZ]; /* nul-terminated built-in country code. ++ * variable length, but fixed size in ++ * struct allows simple allocation for ++ * expected country strings <= 3 chars. ++ */ ++} wl_country_t; ++ ++typedef struct wl_channels_in_country { ++ uint32 buflen; ++ uint32 band; ++ char country_abbrev[WLC_CNTRY_BUF_SZ]; ++ uint32 count; ++ uint32 channel[1]; ++} wl_channels_in_country_t; ++ ++typedef struct wl_country_list { ++ uint32 buflen; ++ uint32 band_set; ++ uint32 band; ++ uint32 count; ++ char country_abbrev[1]; ++} wl_country_list_t; ++ ++#define WL_NUM_RPI_BINS 8 ++#define WL_RM_TYPE_BASIC 1 ++#define WL_RM_TYPE_CCA 2 ++#define WL_RM_TYPE_RPI 3 ++ ++#define WL_RM_FLAG_PARALLEL (1<<0) ++ ++#define WL_RM_FLAG_LATE (1<<1) ++#define WL_RM_FLAG_INCAPABLE (1<<2) ++#define WL_RM_FLAG_REFUSED (1<<3) ++ ++typedef struct wl_rm_req_elt { ++ int8 type; ++ int8 flags; ++ chanspec_t chanspec; ++ uint32 token; /* token for this measurement */ ++ uint32 tsf_h; /* TSF high 32-bits of Measurement start time */ ++ uint32 tsf_l; /* TSF low 32-bits */ ++ uint32 dur; /* TUs */ ++} wl_rm_req_elt_t; ++ ++typedef struct wl_rm_req { ++ uint32 token; /* overall measurement set token */ ++ uint32 count; /* number of measurement requests */ ++ void *cb; /* completion callback function: may be NULL */ ++ void *cb_arg; /* arg to completion callback function */ ++ wl_rm_req_elt_t req[1]; /* variable length block of requests */ ++} wl_rm_req_t; ++#define WL_RM_REQ_FIXED_LEN OFFSETOF(wl_rm_req_t, req) ++ ++typedef struct wl_rm_rep_elt { ++ int8 type; ++ int8 flags; ++ chanspec_t chanspec; ++ uint32 token; /* token for this measurement */ ++ uint32 tsf_h; /* TSF high 32-bits of Measurement start time */ ++ uint32 tsf_l; /* TSF low 32-bits */ ++ uint32 dur; /* TUs */ ++ uint32 len; /* byte length of data block */ ++ uint8 data[1]; /* variable length data block */ ++} wl_rm_rep_elt_t; ++#define WL_RM_REP_ELT_FIXED_LEN 24 /* length excluding data block */ ++ ++#define WL_RPI_REP_BIN_NUM 8 ++typedef struct wl_rm_rpi_rep { ++ uint8 rpi[WL_RPI_REP_BIN_NUM]; ++ int8 rpi_max[WL_RPI_REP_BIN_NUM]; ++} wl_rm_rpi_rep_t; ++ ++typedef struct wl_rm_rep { ++ uint32 token; /* overall measurement set token */ ++ uint32 len; /* length of measurement report block */ ++ wl_rm_rep_elt_t rep[1]; /* variable length block of reports */ ++} wl_rm_rep_t; ++#define WL_RM_REP_FIXED_LEN 8 ++ ++ ++#if defined(BCMSUP_PSK) ++typedef enum sup_auth_status { ++ /* Basic supplicant authentication states */ ++ WLC_SUP_DISCONNECTED = 0, ++ WLC_SUP_CONNECTING, ++ WLC_SUP_IDREQUIRED, ++ WLC_SUP_AUTHENTICATING, ++ WLC_SUP_AUTHENTICATED, ++ WLC_SUP_KEYXCHANGE, ++ WLC_SUP_KEYED, ++ WLC_SUP_TIMEOUT, ++ WLC_SUP_LAST_BASIC_STATE, ++ ++ /* Extended supplicant authentication states */ ++ /* Waiting to receive handshake msg M1 */ ++ WLC_SUP_KEYXCHANGE_WAIT_M1 = WLC_SUP_AUTHENTICATED, ++ /* Preparing to send handshake msg M2 */ ++ WLC_SUP_KEYXCHANGE_PREP_M2 = WLC_SUP_KEYXCHANGE, ++ /* Waiting to receive handshake msg M3 */ ++ WLC_SUP_KEYXCHANGE_WAIT_M3 = WLC_SUP_LAST_BASIC_STATE, ++ WLC_SUP_KEYXCHANGE_PREP_M4, /* Preparing to send handshake msg M4 */ ++ WLC_SUP_KEYXCHANGE_WAIT_G1, /* Waiting to receive handshake msg G1 */ ++ WLC_SUP_KEYXCHANGE_PREP_G2 /* Preparing to send handshake msg G2 */ ++} sup_auth_status_t; ++#endif ++ ++/* Enumerate crypto algorithms */ ++#define CRYPTO_ALGO_OFF 0 ++#define CRYPTO_ALGO_WEP1 1 ++#define CRYPTO_ALGO_TKIP 2 ++#define CRYPTO_ALGO_WEP128 3 ++#define CRYPTO_ALGO_AES_CCM 4 ++#define CRYPTO_ALGO_AES_OCB_MSDU 5 ++#define CRYPTO_ALGO_AES_OCB_MPDU 6 ++#define CRYPTO_ALGO_NALG 7 ++#define CRYPTO_ALGO_PMK 12 /* for 802.1x supp to set PMK before 4-way */ ++ ++#define WSEC_GEN_MIC_ERROR 0x0001 ++#define WSEC_GEN_REPLAY 0x0002 ++#define WSEC_GEN_ICV_ERROR 0x0004 ++#define WSEC_GEN_MFP_ACT_ERROR 0x0008 ++#define WSEC_GEN_MFP_DISASSOC_ERROR 0x0010 ++#define WSEC_GEN_MFP_DEAUTH_ERROR 0x0020 ++ ++#define WL_SOFT_KEY (1 << 0) /* Indicates this key is using soft encrypt */ ++#define WL_PRIMARY_KEY (1 << 1) /* Indicates this key is the primary (ie tx) key */ ++#define WL_KF_RES_4 (1 << 4) /* Reserved for backward compat */ ++#define WL_KF_RES_5 (1 << 5) /* Reserved for backward compat */ ++#define WL_IBSS_PEER_GROUP_KEY (1 << 6) /* Indicates a group key for a IBSS PEER */ ++ ++typedef struct wl_wsec_key { ++ uint32 index; /* key index */ ++ uint32 len; /* key length */ ++ uint8 data[DOT11_MAX_KEY_SIZE]; /* key data */ ++ uint32 pad_1[18]; ++ uint32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ ++ uint32 flags; /* misc flags */ ++ uint32 pad_2[2]; ++ int pad_3; ++ int iv_initialized; /* has IV been initialized already? */ ++ int pad_4; ++ /* Rx IV */ ++ struct { ++ uint32 hi; /* upper 32 bits of IV */ ++ uint16 lo; /* lower 16 bits of IV */ ++ } rxiv; ++ uint32 pad_5[2]; ++ struct ether_addr ea; /* per station */ ++} wl_wsec_key_t; ++ ++#define WSEC_MIN_PSK_LEN 8 ++#define WSEC_MAX_PSK_LEN 64 ++ ++/* Flag for key material needing passhash'ing */ ++#define WSEC_PASSPHRASE (1<<0) ++ ++/* receptacle for WLC_SET_WSEC_PMK parameter */ ++typedef struct { ++ ushort key_len; /* octets in key material */ ++ ushort flags; /* key handling qualification */ ++ uint8 key[WSEC_MAX_PSK_LEN]; /* PMK material */ ++} wsec_pmk_t; ++ ++/* wireless security bitvec */ ++#define WEP_ENABLED 0x0001 ++#define TKIP_ENABLED 0x0002 ++#define AES_ENABLED 0x0004 ++#define WSEC_SWFLAG 0x0008 ++#define SES_OW_ENABLED 0x0040 /* to go into transition mode without setting wep */ ++ ++/* wsec macros for operating on the above definitions */ ++#define WSEC_WEP_ENABLED(wsec) ((wsec) & WEP_ENABLED) ++#define WSEC_TKIP_ENABLED(wsec) ((wsec) & TKIP_ENABLED) ++#define WSEC_AES_ENABLED(wsec) ((wsec) & AES_ENABLED) ++ ++#define WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED)) ++#define WSEC_SES_OW_ENABLED(wsec) ((wsec) & SES_OW_ENABLED) ++ ++#ifdef MFP ++#define MFP_CAPABLE 0x0200 ++#define MFP_REQUIRED 0x0400 ++#define MFP_SHA256 0x0800 /* a special configuration for STA for WIFI test tool */ ++#endif /* MFP */ ++ ++/* WPA authentication mode bitvec */ ++#define WPA_AUTH_DISABLED 0x0000 /* Legacy (i.e., non-WPA) */ ++#define WPA_AUTH_NONE 0x0001 /* none (IBSS) */ ++#define WPA_AUTH_UNSPECIFIED 0x0002 /* over 802.1x */ ++#define WPA_AUTH_PSK 0x0004 /* Pre-shared key */ ++/* #define WPA_AUTH_8021X 0x0020 */ /* 802.1x, reserved */ ++#define WPA2_AUTH_UNSPECIFIED 0x0040 /* over 802.1x */ ++#define WPA2_AUTH_PSK 0x0080 /* Pre-shared key */ ++#define BRCM_AUTH_PSK 0x0100 /* BRCM specific PSK */ ++#define BRCM_AUTH_DPT 0x0200 /* DPT PSK without group keys */ ++#define WPA2_AUTH_MFP 0x1000 /* MFP (11w) in contrast to CCX */ ++#define WPA2_AUTH_TPK 0x2000 /* TDLS Peer Key */ ++#define WPA2_AUTH_FT 0x4000 /* Fast Transition. */ ++#define WPA_AUTH_PFN_ANY 0xffffffff /* for PFN, match only ssid */ ++ ++/* pmkid */ ++#define MAXPMKID 16 ++ ++typedef struct _pmkid { ++ struct ether_addr BSSID; ++ uint8 PMKID[WPA2_PMKID_LEN]; ++} pmkid_t; ++ ++typedef struct _pmkid_list { ++ uint32 npmkid; ++ pmkid_t pmkid[1]; ++} pmkid_list_t; ++ ++typedef struct _pmkid_cand { ++ struct ether_addr BSSID; ++ uint8 preauth; ++} pmkid_cand_t; ++ ++typedef struct _pmkid_cand_list { ++ uint32 npmkid_cand; ++ pmkid_cand_t pmkid_cand[1]; ++} pmkid_cand_list_t; ++ ++typedef struct wl_assoc_info { ++ uint32 req_len; ++ uint32 resp_len; ++ uint32 flags; ++ struct dot11_assoc_req req; ++ struct ether_addr reassoc_bssid; /* used in reassoc's */ ++ struct dot11_assoc_resp resp; ++} wl_assoc_info_t; ++ ++/* flags */ ++#define WLC_ASSOC_REQ_IS_REASSOC 0x01 /* assoc req was actually a reassoc */ ++ ++#ifndef LINUX_POSTMOGRIFY_REMOVAL ++typedef struct wl_led_info { ++ uint32 index; /* led index */ ++ uint32 behavior; ++ uint8 activehi; ++} wl_led_info_t; ++ ++ ++/* srom read/write struct passed through ioctl */ ++typedef struct { ++ uint byteoff; /* byte offset */ ++ uint nbytes; /* number of bytes */ ++ uint16 buf[1]; ++} srom_rw_t; ++ ++/* similar cis (srom or otp) struct [iovar: may not be aligned] */ ++typedef struct { ++ uint32 source; /* cis source */ ++ uint32 byteoff; /* byte offset */ ++ uint32 nbytes; /* number of bytes */ ++ /* data follows here */ ++} cis_rw_t; ++ ++#define WLC_CIS_DEFAULT 0 /* built-in default */ ++#define WLC_CIS_SROM 1 /* source is sprom */ ++#define WLC_CIS_OTP 2 /* source is otp */ ++ ++/* R_REG and W_REG struct passed through ioctl */ ++typedef struct { ++ uint32 byteoff; /* byte offset of the field in d11regs_t */ ++ uint32 val; /* read/write value of the field */ ++ uint32 size; /* sizeof the field */ ++ uint band; /* band (optional) */ ++} rw_reg_t; ++ ++/* Structure used by GET/SET_ATTEN ioctls - it controls power in b/g-band */ ++/* PCL - Power Control Loop */ ++/* current gain setting is replaced by user input */ ++#define WL_ATTEN_APP_INPUT_PCL_OFF 0 /* turn off PCL, apply supplied input */ ++#define WL_ATTEN_PCL_ON 1 /* turn on PCL */ ++/* current gain setting is maintained */ ++#define WL_ATTEN_PCL_OFF 2 /* turn off PCL. */ ++ ++typedef struct { ++ uint16 auto_ctrl; /* WL_ATTEN_XX */ ++ uint16 bb; /* Baseband attenuation */ ++ uint16 radio; /* Radio attenuation */ ++ uint16 txctl1; /* Radio TX_CTL1 value */ ++} atten_t; ++ ++/* Per-AC retry parameters */ ++struct wme_tx_params_s { ++ uint8 short_retry; ++ uint8 short_fallback; ++ uint8 long_retry; ++ uint8 long_fallback; ++ uint16 max_rate; /* In units of 512 Kbps */ ++}; ++ ++typedef struct wme_tx_params_s wme_tx_params_t; ++ ++#define WL_WME_TX_PARAMS_IO_BYTES (sizeof(wme_tx_params_t) * AC_COUNT) ++ ++/* defines used by poweridx iovar - it controls power in a-band */ ++/* current gain setting is maintained */ ++#define WL_PWRIDX_PCL_OFF -2 /* turn off PCL. */ ++#define WL_PWRIDX_PCL_ON -1 /* turn on PCL */ ++#define WL_PWRIDX_LOWER_LIMIT -2 /* lower limit */ ++#define WL_PWRIDX_UPPER_LIMIT 63 /* upper limit */ ++/* value >= 0 causes ++ * - input to be set to that value ++ * - PCL to be off ++ */ ++ ++/* Used to get specific link/ac parameters */ ++typedef struct { ++ int ac; ++ uint8 val; ++ struct ether_addr ea; ++} link_val_t; ++ ++#define BCM_MAC_STATUS_INDICATION (0x40010200L) ++#endif /* LINUX_POSTMOGRIFY_REMOVAL */ ++ ++typedef struct { ++ uint16 ver; /* version of this struct */ ++ uint16 len; /* length in bytes of this structure */ ++ uint16 cap; /* sta's advertised capabilities */ ++ uint32 flags; /* flags defined below */ ++ uint32 idle; /* time since data pkt rx'd from sta */ ++ struct ether_addr ea; /* Station address */ ++ wl_rateset_t rateset; /* rateset in use */ ++ uint32 in; /* seconds elapsed since associated */ ++ uint32 listen_interval_inms; /* Min Listen interval in ms for this STA */ ++ uint32 tx_pkts; /* # of packets transmitted */ ++ uint32 tx_failures; /* # of packets failed */ ++ uint32 rx_ucast_pkts; /* # of unicast packets received */ ++ uint32 rx_mcast_pkts; /* # of multicast packets received */ ++ uint32 tx_rate; /* Rate of last successful tx frame */ ++ uint32 rx_rate; /* Rate of last successful rx frame */ ++ uint32 rx_decrypt_succeeds; /* # of packet decrypted successfully */ ++ uint32 rx_decrypt_failures; /* # of packet decrypted unsuccessfully */ ++} sta_info_t; ++ ++#define WL_OLD_STAINFO_SIZE OFFSETOF(sta_info_t, tx_pkts) ++ ++#define WL_STA_VER 3 ++ ++/* Flags for sta_info_t indicating properties of STA */ ++#define WL_STA_BRCM 0x1 /* Running a Broadcom driver */ ++#define WL_STA_WME 0x2 /* WMM association */ ++#define WL_STA_UNUSED 0x4 ++#define WL_STA_AUTHE 0x8 /* Authenticated */ ++#define WL_STA_ASSOC 0x10 /* Associated */ ++#define WL_STA_AUTHO 0x20 /* Authorized */ ++#define WL_STA_WDS 0x40 /* Wireless Distribution System */ ++#define WL_STA_WDS_LINKUP 0x80 /* WDS traffic/probes flowing properly */ ++#define WL_STA_PS 0x100 /* STA is in power save mode from AP's viewpoint */ ++#define WL_STA_APSD_BE 0x200 /* APSD delv/trigger for AC_BE is default enabled */ ++#define WL_STA_APSD_BK 0x400 /* APSD delv/trigger for AC_BK is default enabled */ ++#define WL_STA_APSD_VI 0x800 /* APSD delv/trigger for AC_VI is default enabled */ ++#define WL_STA_APSD_VO 0x1000 /* APSD delv/trigger for AC_VO is default enabled */ ++#define WL_STA_N_CAP 0x2000 /* STA 802.11n capable */ ++#define WL_STA_SCBSTATS 0x4000 /* Per STA debug stats */ ++ ++#define WL_WDS_LINKUP WL_STA_WDS_LINKUP /* deprecated */ ++ ++/* Values for TX Filter override mode */ ++#define WLC_TXFILTER_OVERRIDE_DISABLED 0 ++#define WLC_TXFILTER_OVERRIDE_ENABLED 1 ++ ++/* Used to get specific STA parameters */ ++typedef struct { ++ uint32 val; ++ struct ether_addr ea; ++} scb_val_t; ++ ++/* Used by iovar versions of some ioctls, i.e. WLC_SCB_AUTHORIZE et al */ ++typedef struct { ++ uint32 code; ++ scb_val_t ioctl_args; ++} authops_t; ++ ++/* channel encoding */ ++typedef struct channel_info { ++ int hw_channel; ++ int target_channel; ++ int scan_channel; ++} channel_info_t; ++ ++/* For ioctls that take a list of MAC addresses */ ++struct maclist { ++ uint count; /* number of MAC addresses */ ++ struct ether_addr ea[1]; /* variable length array of MAC addresses */ ++}; ++ ++/* get pkt count struct passed through ioctl */ ++typedef struct get_pktcnt { ++ uint rx_good_pkt; ++ uint rx_bad_pkt; ++ uint tx_good_pkt; ++ uint tx_bad_pkt; ++ uint rx_ocast_good_pkt; /* unicast packets destined for others */ ++} get_pktcnt_t; ++ ++/* NINTENDO2 */ ++#define LQ_IDX_MIN 0 ++#define LQ_IDX_MAX 1 ++#define LQ_IDX_AVG 2 ++#define LQ_IDX_SUM 2 ++#define LQ_IDX_LAST 3 ++#define LQ_STOP_MONITOR 0 ++#define LQ_START_MONITOR 1 ++ ++/* Get averages RSSI, Rx PHY rate and SNR values */ ++typedef struct { ++ int rssi[LQ_IDX_LAST]; /* Array to keep min, max, avg rssi */ ++ int snr[LQ_IDX_LAST]; /* Array to keep min, max, avg snr */ ++ int isvalid; /* Flag indicating whether above data is valid */ ++} wl_lq_t; /* Link Quality */ ++ ++typedef enum wl_wakeup_reason_type { ++ LCD_ON = 1, ++ LCD_OFF, ++ DRC1_WAKE, ++ DRC2_WAKE, ++ REASON_LAST ++} wl_wr_type_t; ++ ++typedef struct { ++/* Unique filter id */ ++ uint32 id; ++ ++/* stores the reason for the last wake up */ ++ uint8 reason; ++} wl_wr_t; ++ ++/* Get MAC specific rate histogram command */ ++typedef struct { ++ struct ether_addr ea; /* MAC Address */ ++ uint8 ac_cat; /* Access Category */ ++ uint8 num_pkts; /* Number of packet entries to be averaged */ ++} wl_mac_ratehisto_cmd_t; /* MAC Specific Rate Histogram command */ ++ ++/* Get MAC rate histogram response */ ++typedef struct { ++ uint32 rate[WLC_MAXRATE + 1]; /* Rates */ ++ uint32 mcs[WL_RATESET_SZ_HT_MCS * WL_TX_CHAINS_MAX]; /* MCS counts */ ++ uint32 vht[WL_RATESET_SZ_VHT_MCS][WL_TX_CHAINS_MAX]; /* VHT counts */ ++ uint32 tsf_timer[2][2]; /* Start and End time for 8bytes value */ ++} wl_mac_ratehisto_res_t; /* MAC Specific Rate Histogram Response */ ++ ++/* Values for TX Filter override mode */ ++#define WLC_TXFILTER_OVERRIDE_DISABLED 0 ++#define WLC_TXFILTER_OVERRIDE_ENABLED 1 ++ ++#define WL_IOCTL_ACTION_GET 0x0 ++#define WL_IOCTL_ACTION_SET 0x1 ++#define WL_IOCTL_ACTION_OVL_IDX_MASK 0x1e ++#define WL_IOCTL_ACTION_OVL_RSV 0x20 ++#define WL_IOCTL_ACTION_OVL 0x40 ++#define WL_IOCTL_ACTION_MASK 0x7e ++#define WL_IOCTL_ACTION_OVL_SHIFT 1 ++ ++/* Linux network driver ioctl encoding */ ++typedef struct wl_ioctl { ++ uint cmd; /* common ioctl definition */ ++ void *buf; /* pointer to user buffer */ ++ uint len; /* length of user buffer */ ++ uint8 set; /* 1=set IOCTL; 0=query IOCTL */ ++ uint used; /* bytes read or written (optional) */ ++ uint needed; /* bytes needed (optional) */ ++} wl_ioctl_t; ++ ++/* reference to wl_ioctl_t struct used by usermode driver */ ++#define ioctl_subtype set /* subtype param */ ++#define ioctl_pid used /* pid param */ ++#define ioctl_status needed /* status param */ ++ ++/* ++ * Structure for passing hardware and software ++ * revision info up from the driver. ++ */ ++typedef struct wlc_rev_info { ++ uint vendorid; /* PCI vendor id */ ++ uint deviceid; /* device id of chip */ ++ uint radiorev; /* radio revision */ ++ uint chiprev; /* chip revision */ ++ uint corerev; /* core revision */ ++ uint boardid; /* board identifier (usu. PCI sub-device id) */ ++ uint boardvendor; /* board vendor (usu. PCI sub-vendor id) */ ++ uint boardrev; /* board revision */ ++ uint driverrev; /* driver version */ ++ uint ucoderev; /* microcode version */ ++ uint bus; /* bus type */ ++ uint chipnum; /* chip number */ ++ uint phytype; /* phy type */ ++ uint phyrev; /* phy revision */ ++ uint anarev; /* anacore rev */ ++ uint chippkg; /* chip package info */ ++} wlc_rev_info_t; ++ ++#define WL_REV_INFO_LEGACY_LENGTH 48 ++ ++#define WL_BRAND_MAX 10 ++typedef struct wl_instance_info { ++ uint instance; ++ char brand[WL_BRAND_MAX]; ++} wl_instance_info_t; ++ ++/* structure to change size of tx fifo */ ++typedef struct wl_txfifo_sz { ++ uint16 magic; ++ uint16 fifo; ++ uint16 size; ++} wl_txfifo_sz_t; ++/* magic pattern used for mismatch driver and wl */ ++#define WL_TXFIFO_SZ_MAGIC 0xa5a5 ++ ++/* Transfer info about an IOVar from the driver */ ++/* Max supported IOV name size in bytes, + 1 for nul termination */ ++#define WLC_IOV_NAME_LEN 30 ++typedef struct wlc_iov_trx_s { ++ uint8 module; ++ uint8 type; ++ char name[WLC_IOV_NAME_LEN]; ++} wlc_iov_trx_t; ++ ++/* check this magic number */ ++#define WLC_IOCTL_MAGIC 0x14e46c77 ++ ++/* bump this number if you change the ioctl interface */ ++#ifdef D11AC_IOTYPES ++#define WLC_IOCTL_VERSION 2 ++#define WLC_IOCTL_VERSION_LEGACY_IOTYPES 1 ++#else ++#define WLC_IOCTL_VERSION 1 ++#endif /* D11AC_IOTYPES */ ++ ++#define WLC_IOCTL_MAXLEN 8192 /* max length ioctl buffer required */ ++#define WLC_IOCTL_SMLEN 256 /* "small" length ioctl buffer required */ ++#define WLC_IOCTL_MEDLEN 1536 /* "med" length ioctl buffer required */ ++#ifdef WLC_HIGH_ONLY ++#define WLC_SAMPLECOLLECT_MAXLEN 1024 /* limit sample size for bmac */ ++#else ++#if defined(LCNCONF) || defined(LCN40CONF) ++#define WLC_SAMPLECOLLECT_MAXLEN 8192 /* Max Sample Collect buffer */ ++#else ++#define WLC_SAMPLECOLLECT_MAXLEN 10240 /* Max Sample Collect buffer for two cores */ ++#endif ++#endif /* WLC_HIGH_ONLY */ ++ ++/* common ioctl definitions */ ++#define WLC_GET_MAGIC 0 ++#define WLC_GET_VERSION 1 ++#define WLC_UP 2 ++#define WLC_DOWN 3 ++#define WLC_GET_LOOP 4 ++#define WLC_SET_LOOP 5 ++#define WLC_DUMP 6 ++#define WLC_GET_MSGLEVEL 7 ++#define WLC_SET_MSGLEVEL 8 ++#define WLC_GET_PROMISC 9 ++#define WLC_SET_PROMISC 10 ++/* #define WLC_OVERLAY_IOCTL 11 */ /* not supported */ ++#define WLC_GET_RATE 12 ++#define WLC_GET_MAX_RATE 13 ++#define WLC_GET_INSTANCE 14 ++/* #define WLC_GET_FRAG 15 */ /* no longer supported */ ++/* #define WLC_SET_FRAG 16 */ /* no longer supported */ ++/* #define WLC_GET_RTS 17 */ /* no longer supported */ ++/* #define WLC_SET_RTS 18 */ /* no longer supported */ ++#define WLC_GET_INFRA 19 ++#define WLC_SET_INFRA 20 ++#define WLC_GET_AUTH 21 ++#define WLC_SET_AUTH 22 ++#define WLC_GET_BSSID 23 ++#define WLC_SET_BSSID 24 ++#define WLC_GET_SSID 25 ++#define WLC_SET_SSID 26 ++#define WLC_RESTART 27 ++#define WLC_TERMINATED 28 ++/* #define WLC_DUMP_SCB 28 */ /* no longer supported */ ++#define WLC_GET_CHANNEL 29 ++#define WLC_SET_CHANNEL 30 ++#define WLC_GET_SRL 31 ++#define WLC_SET_SRL 32 ++#define WLC_GET_LRL 33 ++#define WLC_SET_LRL 34 ++#define WLC_GET_PLCPHDR 35 ++#define WLC_SET_PLCPHDR 36 ++#define WLC_GET_RADIO 37 ++#define WLC_SET_RADIO 38 ++#define WLC_GET_PHYTYPE 39 ++#define WLC_DUMP_RATE 40 ++#define WLC_SET_RATE_PARAMS 41 ++#define WLC_GET_FIXRATE 42 ++#define WLC_SET_FIXRATE 43 ++/* #define WLC_GET_WEP 42 */ /* no longer supported */ ++/* #define WLC_SET_WEP 43 */ /* no longer supported */ ++#define WLC_GET_KEY 44 ++#define WLC_SET_KEY 45 ++#define WLC_GET_REGULATORY 46 ++#define WLC_SET_REGULATORY 47 ++#define WLC_GET_PASSIVE_SCAN 48 ++#define WLC_SET_PASSIVE_SCAN 49 ++#define WLC_SCAN 50 ++#define WLC_SCAN_RESULTS 51 ++#define WLC_DISASSOC 52 ++#define WLC_REASSOC 53 ++#define WLC_GET_ROAM_TRIGGER 54 ++#define WLC_SET_ROAM_TRIGGER 55 ++#define WLC_GET_ROAM_DELTA 56 ++#define WLC_SET_ROAM_DELTA 57 ++#define WLC_GET_ROAM_SCAN_PERIOD 58 ++#define WLC_SET_ROAM_SCAN_PERIOD 59 ++#define WLC_EVM 60 /* diag */ ++#define WLC_GET_TXANT 61 ++#define WLC_SET_TXANT 62 ++#define WLC_GET_ANTDIV 63 ++#define WLC_SET_ANTDIV 64 ++/* #define WLC_GET_TXPWR 65 */ /* no longer supported */ ++/* #define WLC_SET_TXPWR 66 */ /* no longer supported */ ++#define WLC_GET_CLOSED 67 ++#define WLC_SET_CLOSED 68 ++#define WLC_GET_MACLIST 69 ++#define WLC_SET_MACLIST 70 ++#define WLC_GET_RATESET 71 ++#define WLC_SET_RATESET 72 ++/* #define WLC_GET_LOCALE 73 */ /* no longer supported */ ++#define WLC_LONGTRAIN 74 ++#define WLC_GET_BCNPRD 75 ++#define WLC_SET_BCNPRD 76 ++#define WLC_GET_DTIMPRD 77 ++#define WLC_SET_DTIMPRD 78 ++#define WLC_GET_SROM 79 ++#define WLC_SET_SROM 80 ++#define WLC_GET_WEP_RESTRICT 81 ++#define WLC_SET_WEP_RESTRICT 82 ++#define WLC_GET_COUNTRY 83 ++#define WLC_SET_COUNTRY 84 ++#define WLC_GET_PM 85 ++#define WLC_SET_PM 86 ++#define WLC_GET_WAKE 87 ++#define WLC_SET_WAKE 88 ++/* #define WLC_GET_D11CNTS 89 */ /* -> "counters" iovar */ ++#define WLC_GET_FORCELINK 90 /* ndis only */ ++#define WLC_SET_FORCELINK 91 /* ndis only */ ++#define WLC_FREQ_ACCURACY 92 /* diag */ ++#define WLC_CARRIER_SUPPRESS 93 /* diag */ ++#define WLC_GET_PHYREG 94 ++#define WLC_SET_PHYREG 95 ++#define WLC_GET_RADIOREG 96 ++#define WLC_SET_RADIOREG 97 ++#define WLC_GET_REVINFO 98 ++#define WLC_GET_UCANTDIV 99 ++#define WLC_SET_UCANTDIV 100 ++#define WLC_R_REG 101 ++#define WLC_W_REG 102 ++/* #define WLC_DIAG_LOOPBACK 103 old tray diag */ ++/* #define WLC_RESET_D11CNTS 104 */ /* -> "reset_d11cnts" iovar */ ++#define WLC_GET_MACMODE 105 ++#define WLC_SET_MACMODE 106 ++#define WLC_GET_MONITOR 107 ++#define WLC_SET_MONITOR 108 ++#define WLC_GET_GMODE 109 ++#define WLC_SET_GMODE 110 ++#define WLC_GET_LEGACY_ERP 111 ++#define WLC_SET_LEGACY_ERP 112 ++#define WLC_GET_RX_ANT 113 ++#define WLC_GET_CURR_RATESET 114 /* current rateset */ ++#define WLC_GET_SCANSUPPRESS 115 ++#define WLC_SET_SCANSUPPRESS 116 ++#define WLC_GET_AP 117 ++#define WLC_SET_AP 118 ++#define WLC_GET_EAP_RESTRICT 119 ++#define WLC_SET_EAP_RESTRICT 120 ++#define WLC_SCB_AUTHORIZE 121 ++#define WLC_SCB_DEAUTHORIZE 122 ++#define WLC_GET_WDSLIST 123 ++#define WLC_SET_WDSLIST 124 ++#define WLC_GET_ATIM 125 ++#define WLC_SET_ATIM 126 ++#define WLC_GET_RSSI 127 ++#define WLC_GET_PHYANTDIV 128 ++#define WLC_SET_PHYANTDIV 129 ++#define WLC_AP_RX_ONLY 130 ++#define WLC_GET_TX_PATH_PWR 131 ++#define WLC_SET_TX_PATH_PWR 132 ++#define WLC_GET_WSEC 133 ++#define WLC_SET_WSEC 134 ++#define WLC_GET_PHY_NOISE 135 ++#define WLC_GET_BSS_INFO 136 ++#define WLC_GET_PKTCNTS 137 ++#define WLC_GET_LAZYWDS 138 ++#define WLC_SET_LAZYWDS 139 ++#define WLC_GET_BANDLIST 140 ++#define WLC_GET_BAND 141 ++#define WLC_SET_BAND 142 ++#define WLC_SCB_DEAUTHENTICATE 143 ++#define WLC_GET_SHORTSLOT 144 ++#define WLC_GET_SHORTSLOT_OVERRIDE 145 ++#define WLC_SET_SHORTSLOT_OVERRIDE 146 ++#define WLC_GET_SHORTSLOT_RESTRICT 147 ++#define WLC_SET_SHORTSLOT_RESTRICT 148 ++#define WLC_GET_GMODE_PROTECTION 149 ++#define WLC_GET_GMODE_PROTECTION_OVERRIDE 150 ++#define WLC_SET_GMODE_PROTECTION_OVERRIDE 151 ++#define WLC_UPGRADE 152 ++/* #define WLC_GET_MRATE 153 */ /* no longer supported */ ++/* #define WLC_SET_MRATE 154 */ /* no longer supported */ ++#define WLC_GET_IGNORE_BCNS 155 ++#define WLC_SET_IGNORE_BCNS 156 ++#define WLC_GET_SCB_TIMEOUT 157 ++#define WLC_SET_SCB_TIMEOUT 158 ++#define WLC_GET_ASSOCLIST 159 ++#define WLC_GET_CLK 160 ++#define WLC_SET_CLK 161 ++#define WLC_GET_UP 162 ++#define WLC_OUT 163 ++#define WLC_GET_WPA_AUTH 164 ++#define WLC_SET_WPA_AUTH 165 ++#define WLC_GET_UCFLAGS 166 ++#define WLC_SET_UCFLAGS 167 ++#define WLC_GET_PWRIDX 168 ++#define WLC_SET_PWRIDX 169 ++#define WLC_GET_TSSI 170 ++#define WLC_GET_SUP_RATESET_OVERRIDE 171 ++#define WLC_SET_SUP_RATESET_OVERRIDE 172 ++/* #define WLC_SET_FAST_TIMER 173 */ /* no longer supported */ ++/* #define WLC_GET_FAST_TIMER 174 */ /* no longer supported */ ++/* #define WLC_SET_SLOW_TIMER 175 */ /* no longer supported */ ++/* #define WLC_GET_SLOW_TIMER 176 */ /* no longer supported */ ++/* #define WLC_DUMP_PHYREGS 177 */ /* no longer supported */ ++#define WLC_GET_PROTECTION_CONTROL 178 ++#define WLC_SET_PROTECTION_CONTROL 179 ++#define WLC_GET_PHYLIST 180 ++#define WLC_ENCRYPT_STRENGTH 181 /* ndis only */ ++#define WLC_DECRYPT_STATUS 182 /* ndis only */ ++#define WLC_GET_KEY_SEQ 183 ++#define WLC_GET_SCAN_CHANNEL_TIME 184 ++#define WLC_SET_SCAN_CHANNEL_TIME 185 ++#define WLC_GET_SCAN_UNASSOC_TIME 186 ++#define WLC_SET_SCAN_UNASSOC_TIME 187 ++#define WLC_GET_SCAN_HOME_TIME 188 ++#define WLC_SET_SCAN_HOME_TIME 189 ++#define WLC_GET_SCAN_NPROBES 190 ++#define WLC_SET_SCAN_NPROBES 191 ++#define WLC_GET_PRB_RESP_TIMEOUT 192 ++#define WLC_SET_PRB_RESP_TIMEOUT 193 ++#define WLC_GET_ATTEN 194 ++#define WLC_SET_ATTEN 195 ++#define WLC_GET_SHMEM 196 /* diag */ ++#define WLC_SET_SHMEM 197 /* diag */ ++/* #define WLC_GET_GMODE_PROTECTION_CTS 198 */ /* no longer supported */ ++/* #define WLC_SET_GMODE_PROTECTION_CTS 199 */ /* no longer supported */ ++#define WLC_SET_WSEC_TEST 200 ++#define WLC_SCB_DEAUTHENTICATE_FOR_REASON 201 ++#define WLC_TKIP_COUNTERMEASURES 202 ++#define WLC_GET_PIOMODE 203 ++#define WLC_SET_PIOMODE 204 ++#define WLC_SET_ASSOC_PREFER 205 ++#define WLC_GET_ASSOC_PREFER 206 ++#define WLC_SET_ROAM_PREFER 207 ++#define WLC_GET_ROAM_PREFER 208 ++#define WLC_SET_LED 209 ++#define WLC_GET_LED 210 ++#define WLC_GET_INTERFERENCE_MODE 211 ++#define WLC_SET_INTERFERENCE_MODE 212 ++#define WLC_GET_CHANNEL_QA 213 ++#define WLC_START_CHANNEL_QA 214 ++#define WLC_GET_CHANNEL_SEL 215 ++#define WLC_START_CHANNEL_SEL 216 ++#define WLC_GET_VALID_CHANNELS 217 ++#define WLC_GET_FAKEFRAG 218 ++#define WLC_SET_FAKEFRAG 219 ++#define WLC_GET_PWROUT_PERCENTAGE 220 ++#define WLC_SET_PWROUT_PERCENTAGE 221 ++#define WLC_SET_BAD_FRAME_PREEMPT 222 ++#define WLC_GET_BAD_FRAME_PREEMPT 223 ++#define WLC_SET_LEAP_LIST 224 ++#define WLC_GET_LEAP_LIST 225 ++#define WLC_GET_CWMIN 226 ++#define WLC_SET_CWMIN 227 ++#define WLC_GET_CWMAX 228 ++#define WLC_SET_CWMAX 229 ++#define WLC_GET_WET 230 ++#define WLC_SET_WET 231 ++#define WLC_GET_PUB 232 ++/* #define WLC_SET_GLACIAL_TIMER 233 */ /* no longer supported */ ++/* #define WLC_GET_GLACIAL_TIMER 234 */ /* no longer supported */ ++#define WLC_GET_KEY_PRIMARY 235 ++#define WLC_SET_KEY_PRIMARY 236 ++/* #define WLC_DUMP_RADIOREGS 237 */ /* no longer supported */ ++#define WLC_GET_ACI_ARGS 238 ++#define WLC_SET_ACI_ARGS 239 ++#define WLC_UNSET_CALLBACK 240 ++#define WLC_SET_CALLBACK 241 ++#define WLC_GET_RADAR 242 ++#define WLC_SET_RADAR 243 ++#define WLC_SET_SPECT_MANAGMENT 244 ++#define WLC_GET_SPECT_MANAGMENT 245 ++#define WLC_WDS_GET_REMOTE_HWADDR 246 /* handled in wl_linux.c/wl_vx.c */ ++#define WLC_WDS_GET_WPA_SUP 247 ++#define WLC_SET_CS_SCAN_TIMER 248 ++#define WLC_GET_CS_SCAN_TIMER 249 ++#define WLC_MEASURE_REQUEST 250 ++#define WLC_INIT 251 ++#define WLC_SEND_QUIET 252 ++#define WLC_KEEPALIVE 253 ++#define WLC_SEND_PWR_CONSTRAINT 254 ++#define WLC_UPGRADE_STATUS 255 ++#define WLC_CURRENT_PWR 256 ++#define WLC_GET_SCAN_PASSIVE_TIME 257 ++#define WLC_SET_SCAN_PASSIVE_TIME 258 ++#define WLC_LEGACY_LINK_BEHAVIOR 259 ++#define WLC_GET_CHANNELS_IN_COUNTRY 260 ++#define WLC_GET_COUNTRY_LIST 261 ++#define WLC_GET_VAR 262 /* get value of named variable */ ++#define WLC_SET_VAR 263 /* set named variable to value */ ++#define WLC_NVRAM_GET 264 /* deprecated */ ++#define WLC_NVRAM_SET 265 ++#define WLC_NVRAM_DUMP 266 ++#define WLC_REBOOT 267 ++#define WLC_SET_WSEC_PMK 268 ++#define WLC_GET_AUTH_MODE 269 ++#define WLC_SET_AUTH_MODE 270 ++#define WLC_GET_WAKEENTRY 271 ++#define WLC_SET_WAKEENTRY 272 ++#define WLC_NDCONFIG_ITEM 273 /* currently handled in wl_oid.c */ ++#define WLC_NVOTPW 274 ++#define WLC_OTPW 275 ++#define WLC_IOV_BLOCK_GET 276 ++#define WLC_IOV_MODULES_GET 277 ++#define WLC_SOFT_RESET 278 ++#define WLC_GET_ALLOW_MODE 279 ++#define WLC_SET_ALLOW_MODE 280 ++#define WLC_GET_DESIRED_BSSID 281 ++#define WLC_SET_DESIRED_BSSID 282 ++#define WLC_DISASSOC_MYAP 283 ++#define WLC_GET_NBANDS 284 /* for Dongle EXT_STA support */ ++#define WLC_GET_BANDSTATES 285 /* for Dongle EXT_STA support */ ++#define WLC_GET_WLC_BSS_INFO 286 /* for Dongle EXT_STA support */ ++#define WLC_GET_ASSOC_INFO 287 /* for Dongle EXT_STA support */ ++#define WLC_GET_OID_PHY 288 /* for Dongle EXT_STA support */ ++#define WLC_SET_OID_PHY 289 /* for Dongle EXT_STA support */ ++#define WLC_SET_ASSOC_TIME 290 /* for Dongle EXT_STA support */ ++#define WLC_GET_DESIRED_SSID 291 /* for Dongle EXT_STA support */ ++#define WLC_GET_CHANSPEC 292 /* for Dongle EXT_STA support */ ++#define WLC_GET_ASSOC_STATE 293 /* for Dongle EXT_STA support */ ++#define WLC_SET_PHY_STATE 294 /* for Dongle EXT_STA support */ ++#define WLC_GET_SCAN_PENDING 295 /* for Dongle EXT_STA support */ ++#define WLC_GET_SCANREQ_PENDING 296 /* for Dongle EXT_STA support */ ++#define WLC_GET_PREV_ROAM_REASON 297 /* for Dongle EXT_STA support */ ++#define WLC_SET_PREV_ROAM_REASON 298 /* for Dongle EXT_STA support */ ++#define WLC_GET_BANDSTATES_PI 299 /* for Dongle EXT_STA support */ ++#define WLC_GET_PHY_STATE 300 /* for Dongle EXT_STA support */ ++#define WLC_GET_BSS_WPA_RSN 301 /* for Dongle EXT_STA support */ ++#define WLC_GET_BSS_WPA2_RSN 302 /* for Dongle EXT_STA support */ ++#define WLC_GET_BSS_BCN_TS 303 /* for Dongle EXT_STA support */ ++#define WLC_GET_INT_DISASSOC 304 /* for Dongle EXT_STA support */ ++#define WLC_SET_NUM_PEERS 305 /* for Dongle EXT_STA support */ ++#define WLC_GET_NUM_BSS 306 /* for Dongle EXT_STA support */ ++#define WLC_PHY_SAMPLE_COLLECT 307 /* phy sample collect mode */ ++/* #define WLC_UM_PRIV 308 */ /* Deprecated: usermode driver */ ++#define WLC_GET_CMD 309 ++/* #define WLC_LAST 310 */ /* Never used - can be reused */ ++#define WLC_SET_INTERFERENCE_OVERRIDE_MODE 311 /* set inter mode override */ ++#define WLC_GET_INTERFERENCE_OVERRIDE_MODE 312 /* get inter mode override */ ++/* #define WLC_GET_WAI_RESTRICT 313 */ /* for WAPI, deprecated use iovar instead */ ++/* #define WLC_SET_WAI_RESTRICT 314 */ /* for WAPI, deprecated use iovar instead */ ++/* #define WLC_SET_WAI_REKEY 315 */ /* for WAPI, deprecated use iovar instead */ ++#define WLC_SET_NAT_CONFIG 316 /* for configuring NAT filter driver */ ++#define WLC_GET_NAT_STATE 317 ++#define WLC_LAST 318 ++ ++#ifndef EPICTRL_COOKIE ++#define EPICTRL_COOKIE 0xABADCEDE ++#endif ++ ++/* vx wlc ioctl's offset */ ++#define CMN_IOCTL_OFF 0x180 ++ ++/* ++ * custom OID support ++ * ++ * 0xFF - implementation specific OID ++ * 0xE4 - first byte of Broadcom PCI vendor ID ++ * 0x14 - second byte of Broadcom PCI vendor ID ++ * 0xXX - the custom OID number ++ */ ++ ++/* begin 0x1f values beyond the start of the ET driver range. */ ++#define WL_OID_BASE 0xFFE41420 ++ ++/* NDIS overrides */ ++#define OID_WL_GETINSTANCE (WL_OID_BASE + WLC_GET_INSTANCE) ++#define OID_WL_GET_FORCELINK (WL_OID_BASE + WLC_GET_FORCELINK) ++#define OID_WL_SET_FORCELINK (WL_OID_BASE + WLC_SET_FORCELINK) ++#define OID_WL_ENCRYPT_STRENGTH (WL_OID_BASE + WLC_ENCRYPT_STRENGTH) ++#define OID_WL_DECRYPT_STATUS (WL_OID_BASE + WLC_DECRYPT_STATUS) ++#define OID_LEGACY_LINK_BEHAVIOR (WL_OID_BASE + WLC_LEGACY_LINK_BEHAVIOR) ++#define OID_WL_NDCONFIG_ITEM (WL_OID_BASE + WLC_NDCONFIG_ITEM) ++ ++/* EXT_STA Dongle suuport */ ++#define OID_STA_CHANSPEC (WL_OID_BASE + WLC_GET_CHANSPEC) ++#define OID_STA_NBANDS (WL_OID_BASE + WLC_GET_NBANDS) ++#define OID_STA_GET_PHY (WL_OID_BASE + WLC_GET_OID_PHY) ++#define OID_STA_SET_PHY (WL_OID_BASE + WLC_SET_OID_PHY) ++#define OID_STA_ASSOC_TIME (WL_OID_BASE + WLC_SET_ASSOC_TIME) ++#define OID_STA_DESIRED_SSID (WL_OID_BASE + WLC_GET_DESIRED_SSID) ++#define OID_STA_SET_PHY_STATE (WL_OID_BASE + WLC_SET_PHY_STATE) ++#define OID_STA_SCAN_PENDING (WL_OID_BASE + WLC_GET_SCAN_PENDING) ++#define OID_STA_SCANREQ_PENDING (WL_OID_BASE + WLC_GET_SCANREQ_PENDING) ++#define OID_STA_GET_ROAM_REASON (WL_OID_BASE + WLC_GET_PREV_ROAM_REASON) ++#define OID_STA_SET_ROAM_REASON (WL_OID_BASE + WLC_SET_PREV_ROAM_REASON) ++#define OID_STA_GET_PHY_STATE (WL_OID_BASE + WLC_GET_PHY_STATE) ++#define OID_STA_INT_DISASSOC (WL_OID_BASE + WLC_GET_INT_DISASSOC) ++#define OID_STA_SET_NUM_PEERS (WL_OID_BASE + WLC_SET_NUM_PEERS) ++#define OID_STA_GET_NUM_BSS (WL_OID_BASE + WLC_GET_NUM_BSS) ++ ++/* NAT filter driver support */ ++#define OID_NAT_SET_CONFIG (WL_OID_BASE + WLC_SET_NAT_CONFIG) ++#define OID_NAT_GET_STATE (WL_OID_BASE + WLC_GET_NAT_STATE) ++ ++#define WL_DECRYPT_STATUS_SUCCESS 1 ++#define WL_DECRYPT_STATUS_FAILURE 2 ++#define WL_DECRYPT_STATUS_UNKNOWN 3 ++ ++/* allows user-mode app to poll the status of USB image upgrade */ ++#define WLC_UPGRADE_SUCCESS 0 ++#define WLC_UPGRADE_PENDING 1 ++ ++#ifdef CONFIG_USBRNDIS_RETAIL ++/* struct passed in for WLC_NDCONFIG_ITEM */ ++typedef struct { ++ char *name; ++ void *param; ++} ndconfig_item_t; ++#endif ++ ++ ++/* WLC_GET_AUTH, WLC_SET_AUTH values */ ++#define WL_AUTH_OPEN_SYSTEM 0 /* d11 open authentication */ ++#define WL_AUTH_SHARED_KEY 1 /* d11 shared authentication */ ++#define WL_AUTH_OPEN_SHARED 2 /* try open, then shared if open failed w/rc 13 */ ++ ++/* Bit masks for radio disabled status - returned by WL_GET_RADIO */ ++#define WL_RADIO_SW_DISABLE (1<<0) ++#define WL_RADIO_HW_DISABLE (1<<1) ++#define WL_RADIO_MPC_DISABLE (1<<2) ++#define WL_RADIO_COUNTRY_DISABLE (1<<3) /* some countries don't support any channel */ ++ ++#define WL_SPURAVOID_OFF 0 ++#define WL_SPURAVOID_ON1 1 ++#define WL_SPURAVOID_ON2 2 ++ ++/* Override bit for WLC_SET_TXPWR. if set, ignore other level limits */ ++#define WL_TXPWR_OVERRIDE (1U<<31) ++#define WL_TXPWR_NEG (1U<<30) ++ ++#define WL_PHY_PAVARS_LEN 32 /* Phy type, Band range, chain, a1[0], b0[0], b1[0] ... */ ++ ++#define WL_PHY_PAVARS2_NUM 3 /* a1, b0, b1 */ ++#define WL_PHY_PAVAR_VER 1 /* pavars version */ ++typedef struct wl_pavars2 { ++ uint16 ver; /* version of this struct */ ++ uint16 len; /* len of this structure */ ++ uint16 inuse; /* driver return 1 for a1,b0,b1 in current band range */ ++ uint16 phy_type; /* phy type */ ++ uint16 bandrange; ++ uint16 chain; ++ uint16 inpa[WL_PHY_PAVARS2_NUM]; /* phy pavars for one band range */ ++} wl_pavars2_t; ++ ++typedef struct wl_po { ++ uint16 phy_type; /* Phy type */ ++ uint16 band; ++ uint16 cckpo; ++ uint32 ofdmpo; ++ uint16 mcspo[8]; ++} wl_po_t; ++ ++/* a large TX Power as an init value to factor out of MIN() calculations, ++ * keep low enough to fit in an int8, units are .25 dBm ++ */ ++#define WLC_TXPWR_MAX (127) /* ~32 dBm = 1,500 mW */ ++ ++/* "diag" iovar argument and error code */ ++#define WL_DIAG_INTERRUPT 1 /* d11 loopback interrupt test */ ++#define WL_DIAG_LOOPBACK 2 /* d11 loopback data test */ ++#define WL_DIAG_MEMORY 3 /* d11 memory test */ ++#define WL_DIAG_LED 4 /* LED test */ ++#define WL_DIAG_REG 5 /* d11/phy register test */ ++#define WL_DIAG_SROM 6 /* srom read/crc test */ ++#define WL_DIAG_DMA 7 /* DMA test */ ++#define WL_DIAG_LOOPBACK_EXT 8 /* enhenced d11 loopback data test */ ++ ++#define WL_DIAGERR_SUCCESS 0 ++#define WL_DIAGERR_FAIL_TO_RUN 1 /* unable to run requested diag */ ++#define WL_DIAGERR_NOT_SUPPORTED 2 /* diag requested is not supported */ ++#define WL_DIAGERR_INTERRUPT_FAIL 3 /* loopback interrupt test failed */ ++#define WL_DIAGERR_LOOPBACK_FAIL 4 /* loopback data test failed */ ++#define WL_DIAGERR_SROM_FAIL 5 /* srom read failed */ ++#define WL_DIAGERR_SROM_BADCRC 6 /* srom crc failed */ ++#define WL_DIAGERR_REG_FAIL 7 /* d11/phy register test failed */ ++#define WL_DIAGERR_MEMORY_FAIL 8 /* d11 memory test failed */ ++#define WL_DIAGERR_NOMEM 9 /* diag test failed due to no memory */ ++#define WL_DIAGERR_DMA_FAIL 10 /* DMA test failed */ ++ ++#define WL_DIAGERR_MEMORY_TIMEOUT 11 /* d11 memory test didn't finish in time */ ++#define WL_DIAGERR_MEMORY_BADPATTERN 12 /* d11 memory test result in bad pattern */ ++ ++/* band types */ ++#define WLC_BAND_AUTO 0 /* auto-select */ ++#define WLC_BAND_5G 1 /* 5 Ghz */ ++#define WLC_BAND_2G 2 /* 2.4 Ghz */ ++#define WLC_BAND_ALL 3 /* all bands */ ++ ++/* band range returned by band_range iovar */ ++#define WL_CHAN_FREQ_RANGE_2G 0 ++#define WL_CHAN_FREQ_RANGE_5GL 1 ++#define WL_CHAN_FREQ_RANGE_5GM 2 ++#define WL_CHAN_FREQ_RANGE_5GH 3 ++ ++#define WL_CHAN_FREQ_RANGE_5GLL_5BAND 4 ++#define WL_CHAN_FREQ_RANGE_5GLH_5BAND 5 ++#define WL_CHAN_FREQ_RANGE_5GML_5BAND 6 ++#define WL_CHAN_FREQ_RANGE_5GMH_5BAND 7 ++#define WL_CHAN_FREQ_RANGE_5GH_5BAND 8 ++ ++#define WL_CHAN_FREQ_RANGE_5G_BAND0 1 ++#define WL_CHAN_FREQ_RANGE_5G_BAND1 2 ++#define WL_CHAN_FREQ_RANGE_5G_BAND2 3 ++#define WL_CHAN_FREQ_RANGE_5G_BAND3 4 ++ ++#define WL_CHAN_FREQ_RANGE_5G_4BAND 5 ++ ++/* phy types (returned by WLC_GET_PHYTPE) */ ++#define WLC_PHY_TYPE_A 0 ++#define WLC_PHY_TYPE_B 1 ++#define WLC_PHY_TYPE_G 2 ++#define WLC_PHY_TYPE_N 4 ++#define WLC_PHY_TYPE_LP 5 ++#define WLC_PHY_TYPE_SSN 6 ++#define WLC_PHY_TYPE_HT 7 ++#define WLC_PHY_TYPE_LCN 8 ++#define WLC_PHY_TYPE_LCN40 10 ++#define WLC_PHY_TYPE_AC 11 ++#define WLC_PHY_TYPE_NULL 0xf ++ ++/* MAC list modes */ ++#define WLC_MACMODE_DISABLED 0 /* MAC list disabled */ ++#define WLC_MACMODE_DENY 1 /* Deny specified (i.e. allow unspecified) */ ++#define WLC_MACMODE_ALLOW 2 /* Allow specified (i.e. deny unspecified) */ ++ ++/* ++ * 54g modes (basic bits may still be overridden) ++ * ++ * GMODE_LEGACY_B Rateset: 1b, 2b, 5.5, 11 ++ * Preamble: Long ++ * Shortslot: Off ++ * GMODE_AUTO Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54 ++ * Extended Rateset: 6, 9, 12, 48 ++ * Preamble: Long ++ * Shortslot: Auto ++ * GMODE_ONLY Rateset: 1b, 2b, 5.5b, 11b, 18, 24b, 36, 54 ++ * Extended Rateset: 6b, 9, 12b, 48 ++ * Preamble: Short required ++ * Shortslot: Auto ++ * GMODE_B_DEFERRED Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54 ++ * Extended Rateset: 6, 9, 12, 48 ++ * Preamble: Long ++ * Shortslot: On ++ * GMODE_PERFORMANCE Rateset: 1b, 2b, 5.5b, 6b, 9, 11b, 12b, 18, 24b, 36, 48, 54 ++ * Preamble: Short required ++ * Shortslot: On and required ++ * GMODE_LRS Rateset: 1b, 2b, 5.5b, 11b ++ * Extended Rateset: 6, 9, 12, 18, 24, 36, 48, 54 ++ * Preamble: Long ++ * Shortslot: Auto ++ */ ++#define GMODE_LEGACY_B 0 ++#define GMODE_AUTO 1 ++#define GMODE_ONLY 2 ++#define GMODE_B_DEFERRED 3 ++#define GMODE_PERFORMANCE 4 ++#define GMODE_LRS 5 ++#define GMODE_MAX 6 ++ ++/* values for PLCPHdr_override */ ++#define WLC_PLCP_AUTO -1 ++#define WLC_PLCP_SHORT 0 ++#define WLC_PLCP_LONG 1 ++ ++/* values for g_protection_override and n_protection_override */ ++#define WLC_PROTECTION_AUTO -1 ++#define WLC_PROTECTION_OFF 0 ++#define WLC_PROTECTION_ON 1 ++#define WLC_PROTECTION_MMHDR_ONLY 2 ++#define WLC_PROTECTION_CTS_ONLY 3 ++ ++/* values for g_protection_control and n_protection_control */ ++#define WLC_PROTECTION_CTL_OFF 0 ++#define WLC_PROTECTION_CTL_LOCAL 1 ++#define WLC_PROTECTION_CTL_OVERLAP 2 ++ ++/* values for n_protection */ ++#define WLC_N_PROTECTION_OFF 0 ++#define WLC_N_PROTECTION_OPTIONAL 1 ++#define WLC_N_PROTECTION_20IN40 2 ++#define WLC_N_PROTECTION_MIXEDMODE 3 ++ ++/* values for n_preamble_type */ ++#define WLC_N_PREAMBLE_MIXEDMODE 0 ++#define WLC_N_PREAMBLE_GF 1 ++#define WLC_N_PREAMBLE_GF_BRCM 2 ++ ++/* values for band specific 40MHz capabilities (deprecated) */ ++#define WLC_N_BW_20ALL 0 ++#define WLC_N_BW_40ALL 1 ++#define WLC_N_BW_20IN2G_40IN5G 2 ++ ++#define WLC_BW_20MHZ_BIT (1<<0) ++#define WLC_BW_40MHZ_BIT (1<<1) ++#define WLC_BW_80MHZ_BIT (1<<2) ++ ++/* Bandwidth capabilities */ ++#define WLC_BW_CAP_20MHZ (WLC_BW_20MHZ_BIT) ++#define WLC_BW_CAP_40MHZ (WLC_BW_40MHZ_BIT|WLC_BW_20MHZ_BIT) ++#define WLC_BW_CAP_80MHZ (WLC_BW_80MHZ_BIT|WLC_BW_40MHZ_BIT|WLC_BW_20MHZ_BIT) ++#define WLC_BW_CAP_UNRESTRICTED 0xFF ++ ++#define WL_BW_CAP_20MHZ(bw_cap) (((bw_cap) & WLC_BW_20MHZ_BIT) ? TRUE : FALSE) ++#define WL_BW_CAP_40MHZ(bw_cap) (((bw_cap) & WLC_BW_40MHZ_BIT) ? TRUE : FALSE) ++#define WL_BW_CAP_80MHZ(bw_cap) (((bw_cap) & WLC_BW_80MHZ_BIT) ? TRUE : FALSE) ++ ++/* values to force tx/rx chain */ ++#define WLC_N_TXRX_CHAIN0 0 ++#define WLC_N_TXRX_CHAIN1 1 ++ ++/* bitflags for SGI support (sgi_rx iovar) */ ++#define WLC_N_SGI_20 0x01 ++#define WLC_N_SGI_40 0x02 ++ ++/* when sgi_tx==WLC_SGI_ALL, bypass rate selection, enable sgi for all mcs */ ++#define WLC_SGI_ALL 0x02 ++ ++/* Values for PM */ ++#define PM_OFF 0 ++#define PM_MAX 1 ++#define PM_FAST 2 ++#define PM_FORCE_OFF 3 /* use this bit to force PM off even bt is active */ ++ ++#define LISTEN_INTERVAL 10 ++/* interference mitigation options */ ++#define INTERFERE_OVRRIDE_OFF -1 /* interference override off */ ++#define INTERFERE_NONE 0 /* off */ ++#define NON_WLAN 1 /* foreign/non 802.11 interference, no auto detect */ ++#define WLAN_MANUAL 2 /* ACI: no auto detection */ ++#define WLAN_AUTO 3 /* ACI: auto detect */ ++#define WLAN_AUTO_W_NOISE 4 /* ACI: auto - detect and non 802.11 interference */ ++#define AUTO_ACTIVE (1 << 7) /* Auto is currently active */ ++ ++typedef struct wl_aci_args { ++ int enter_aci_thresh; /* Trigger level to start detecting ACI */ ++ int exit_aci_thresh; /* Trigger level to exit ACI mode */ ++ int usec_spin; /* microsecs to delay between rssi samples */ ++ int glitch_delay; /* interval between ACI scans when glitch count is consistently high */ ++ uint16 nphy_adcpwr_enter_thresh; /* ADC power to enter ACI mitigation mode */ ++ uint16 nphy_adcpwr_exit_thresh; /* ADC power to exit ACI mitigation mode */ ++ uint16 nphy_repeat_ctr; /* Number of tries per channel to compute power */ ++ uint16 nphy_num_samples; /* Number of samples to compute power on one channel */ ++ uint16 nphy_undetect_window_sz; /* num of undetects to exit ACI Mitigation mode */ ++ uint16 nphy_b_energy_lo_aci; /* low ACI power energy threshold for bphy */ ++ uint16 nphy_b_energy_md_aci; /* mid ACI power energy threshold for bphy */ ++ uint16 nphy_b_energy_hi_aci; /* high ACI power energy threshold for bphy */ ++ uint16 nphy_noise_noassoc_glitch_th_up; /* wl interference 4 */ ++ uint16 nphy_noise_noassoc_glitch_th_dn; ++ uint16 nphy_noise_assoc_glitch_th_up; ++ uint16 nphy_noise_assoc_glitch_th_dn; ++ uint16 nphy_noise_assoc_aci_glitch_th_up; ++ uint16 nphy_noise_assoc_aci_glitch_th_dn; ++ uint16 nphy_noise_assoc_enter_th; ++ uint16 nphy_noise_noassoc_enter_th; ++ uint16 nphy_noise_assoc_rx_glitch_badplcp_enter_th; ++ uint16 nphy_noise_noassoc_crsidx_incr; ++ uint16 nphy_noise_assoc_crsidx_incr; ++ uint16 nphy_noise_crsidx_decr; ++} wl_aci_args_t; ++ ++#define TRIGGER_NOW 0 ++#define TRIGGER_CRS 0x01 ++#define TRIGGER_CRSDEASSERT 0x02 ++#define TRIGGER_GOODFCS 0x04 ++#define TRIGGER_BADFCS 0x08 ++#define TRIGGER_BADPLCP 0x10 ++#define TRIGGER_CRSGLITCH 0x20 ++#define WL_ACI_ARGS_LEGACY_LENGTH 16 /* bytes of pre NPHY aci args */ ++#define WL_SAMPLECOLLECT_T_VERSION 2 /* version of wl_samplecollect_args_t struct */ ++typedef struct wl_samplecollect_args { ++ /* version 0 fields */ ++ uint8 coll_us; ++ int cores; ++ /* add'l version 1 fields */ ++ uint16 version; /* see definition of WL_SAMPLECOLLECT_T_VERSION */ ++ uint16 length; /* length of entire structure */ ++ int8 trigger; ++ uint16 timeout; ++ uint16 mode; ++ uint32 pre_dur; ++ uint32 post_dur; ++ uint8 gpio_sel; ++ bool downsamp; ++ bool be_deaf; ++ bool agc; /* loop from init gain and going down */ ++ bool filter; /* override high pass corners to lowest */ ++ /* add'l version 2 fields */ ++ uint8 trigger_state; ++ uint8 module_sel1; ++ uint8 module_sel2; ++ uint16 nsamps; ++} wl_samplecollect_args_t; ++ ++#define WL_SAMPLEDATA_HEADER_TYPE 1 ++#define WL_SAMPLEDATA_HEADER_SIZE 80 /* sample collect header size (bytes) */ ++#define WL_SAMPLEDATA_TYPE 2 ++#define WL_SAMPLEDATA_SEQ 0xff /* sequence # */ ++#define WL_SAMPLEDATA_MORE_DATA 0x100 /* more data mask */ ++#define WL_SAMPLEDATA_T_VERSION 1 /* version of wl_samplecollect_args_t struct */ ++/* version for unpacked sample data, int16 {(I,Q),Core(0..N)} */ ++#define WL_SAMPLEDATA_T_VERSION_SPEC_AN 2 ++ ++typedef struct wl_sampledata { ++ uint16 version; /* structure version */ ++ uint16 size; /* size of structure */ ++ uint16 tag; /* Header/Data */ ++ uint16 length; /* data length */ ++ uint32 flag; /* bit def */ ++} wl_sampledata_t; ++ ++#ifndef LINUX_POSTMOGRIFY_REMOVAL ++/* wl_radar_args_t */ ++typedef struct { ++ int npulses; /* required number of pulses at n * t_int */ ++ int ncontig; /* required number of pulses at t_int */ ++ int min_pw; /* minimum pulse width (20 MHz clocks) */ ++ int max_pw; /* maximum pulse width (20 MHz clocks) */ ++ uint16 thresh0; /* Radar detection, thresh 0 */ ++ uint16 thresh1; /* Radar detection, thresh 1 */ ++ uint16 blank; /* Radar detection, blank control */ ++ uint16 fmdemodcfg; /* Radar detection, fmdemod config */ ++ int npulses_lp; /* Radar detection, minimum long pulses */ ++ int min_pw_lp; /* Minimum pulsewidth for long pulses */ ++ int max_pw_lp; /* Maximum pulsewidth for long pulses */ ++ int min_fm_lp; /* Minimum fm for long pulses */ ++ int max_span_lp; /* Maximum deltat for long pulses */ ++ int min_deltat; /* Minimum spacing between pulses */ ++ int max_deltat; /* Maximum spacing between pulses */ ++ uint16 autocorr; /* Radar detection, autocorr on or off */ ++ uint16 st_level_time; /* Radar detection, start_timing level */ ++ uint16 t2_min; /* minimum clocks needed to remain in state 2 */ ++ uint32 version; /* version */ ++ uint32 fra_pulse_err; /* sample error margin for detecting French radar pulsed */ ++ int npulses_fra; /* Radar detection, minimum French pulses set */ ++ int npulses_stg2; /* Radar detection, minimum staggered-2 pulses set */ ++ int npulses_stg3; /* Radar detection, minimum staggered-3 pulses set */ ++ uint16 percal_mask; /* defines which period cal is masked from radar detection */ ++ int quant; /* quantization resolution to pulse positions */ ++ uint32 min_burst_intv_lp; /* minimum burst to burst interval for bin3 radar */ ++ uint32 max_burst_intv_lp; /* maximum burst to burst interval for bin3 radar */ ++ int nskip_rst_lp; /* number of skipped pulses before resetting lp buffer */ ++ int max_pw_tol; /* maximum tollerance allowed in detected pulse width for radar detection */ ++ uint16 feature_mask; /* 16-bit mask to specify enabled features */ ++} wl_radar_args_t; ++ ++#define WL_RADAR_ARGS_VERSION 2 ++ ++typedef struct { ++ uint32 version; /* version */ ++ uint16 thresh0_20_lo; /* Radar detection, thresh 0 (range 5250-5350MHz) for BW 20MHz */ ++ uint16 thresh1_20_lo; /* Radar detection, thresh 1 (range 5250-5350MHz) for BW 20MHz */ ++ uint16 thresh0_40_lo; /* Radar detection, thresh 0 (range 5250-5350MHz) for BW 40MHz */ ++ uint16 thresh1_40_lo; /* Radar detection, thresh 1 (range 5250-5350MHz) for BW 40MHz */ ++ uint16 thresh0_80_lo; /* Radar detection, thresh 0 (range 5250-5350MHz) for BW 80MHz */ ++ uint16 thresh1_80_lo; /* Radar detection, thresh 1 (range 5250-5350MHz) for BW 80MHz */ ++ uint16 thresh0_160_lo; /* Radar detection, thresh 0 (range 5250-5350MHz) for BW 160MHz */ ++ uint16 thresh1_160_lo; /* Radar detection, thresh 1 (range 5250-5350MHz) for BW 160MHz */ ++ uint16 thresh0_20_hi; /* Radar detection, thresh 0 (range 5470-5725MHz) for BW 20MHz */ ++ uint16 thresh1_20_hi; /* Radar detection, thresh 1 (range 5470-5725MHz) for BW 20MHz */ ++ uint16 thresh0_40_hi; /* Radar detection, thresh 0 (range 5470-5725MHz) for BW 40MHz */ ++ uint16 thresh1_40_hi; /* Radar detection, thresh 1 (range 5470-5725MHz) for BW 40MHz */ ++ uint16 thresh0_80_hi; /* Radar detection, thresh 0 (range 5470-5725MHz) for BW 80MHz */ ++ uint16 thresh1_80_hi; /* Radar detection, thresh 1 (range 5470-5725MHz) for BW 80MHz */ ++ uint16 thresh0_160_hi; /* Radar detection, thresh 0 (range 5470-5725MHz) for BW 160MHz */ ++ uint16 thresh1_160_hi; /* Radar detection, thresh 1 (range 5470-5725MHz) for BW 160MHz */ ++} wl_radar_thr_t; ++ ++#define WL_RADAR_THR_VERSION 2 ++#define WL_THRESHOLD_LO_BAND 70 /* range from 5250MHz - 5350MHz */ ++ ++/* radar iovar SET defines */ ++#define WL_RADAR_DETECTOR_OFF 0 /* radar detector off */ ++#define WL_RADAR_DETECTOR_ON 1 /* radar detector on */ ++#define WL_RADAR_SIMULATED 2 /* force radar detector to declare ++ * detection once ++ */ ++#define WL_RSSI_ANT_VERSION 1 /* current version of wl_rssi_ant_t */ ++#define WL_ANT_RX_MAX 2 /* max 2 receive antennas */ ++#define WL_ANT_HT_RX_MAX 3 /* max 3 receive antennas/cores */ ++#define WL_ANT_IDX_1 0 /* antenna index 1 */ ++#define WL_ANT_IDX_2 1 /* antenna index 2 */ ++ ++#ifndef WL_RSSI_ANT_MAX ++#define WL_RSSI_ANT_MAX 4 /* max possible rx antennas */ ++#elif WL_RSSI_ANT_MAX != 4 ++#error "WL_RSSI_ANT_MAX does not match" ++#endif ++ ++/* RSSI per antenna */ ++typedef struct { ++ uint32 version; /* version field */ ++ uint32 count; /* number of valid antenna rssi */ ++ int8 rssi_ant[WL_RSSI_ANT_MAX]; /* rssi per antenna */ ++} wl_rssi_ant_t; ++ ++/* dfs_status iovar-related defines */ ++ ++/* cac - channel availability check, ++ * ism - in-service monitoring ++ * csa - channel switching announcement ++ */ ++ ++/* cac state values */ ++#define WL_DFS_CACSTATE_IDLE 0 /* state for operating in non-radar channel */ ++#define WL_DFS_CACSTATE_PREISM_CAC 1 /* CAC in progress */ ++#define WL_DFS_CACSTATE_ISM 2 /* ISM in progress */ ++#define WL_DFS_CACSTATE_CSA 3 /* csa */ ++#define WL_DFS_CACSTATE_POSTISM_CAC 4 /* ISM CAC */ ++#define WL_DFS_CACSTATE_PREISM_OOC 5 /* PREISM OOC */ ++#define WL_DFS_CACSTATE_POSTISM_OOC 6 /* POSTISM OOC */ ++#define WL_DFS_CACSTATES 7 /* this many states exist */ ++ ++/* data structure used in 'dfs_status' wl interface, which is used to query dfs status */ ++typedef struct { ++ uint state; /* noted by WL_DFS_CACSTATE_XX. */ ++ uint duration; /* time spent in ms in state. */ ++ /* as dfs enters ISM state, it removes the operational channel from quiet channel ++ * list and notes the channel in channel_cleared. set to 0 if no channel is cleared ++ */ ++ chanspec_t chanspec_cleared; ++ /* chanspec cleared used to be a uint, add another to uint16 to maintain size */ ++ uint16 pad; ++} wl_dfs_status_t; ++ ++#define NUM_PWRCTRL_RATES 12 ++ ++typedef struct { ++ uint8 txpwr_band_max[NUM_PWRCTRL_RATES]; /* User set target */ ++ uint8 txpwr_limit[NUM_PWRCTRL_RATES]; /* reg and local power limit */ ++ uint8 txpwr_local_max; /* local max according to the AP */ ++ uint8 txpwr_local_constraint; /* local constraint according to the AP */ ++ uint8 txpwr_chan_reg_max; /* Regulatory max for this channel */ ++ uint8 txpwr_target[2][NUM_PWRCTRL_RATES]; /* Latest target for 2.4 and 5 Ghz */ ++ uint8 txpwr_est_Pout[2]; /* Latest estimate for 2.4 and 5 Ghz */ ++ uint8 txpwr_opo[NUM_PWRCTRL_RATES]; /* On G phy, OFDM power offset */ ++ uint8 txpwr_bphy_cck_max[NUM_PWRCTRL_RATES]; /* Max CCK power for this band (SROM) */ ++ uint8 txpwr_bphy_ofdm_max; /* Max OFDM power for this band (SROM) */ ++ uint8 txpwr_aphy_max[NUM_PWRCTRL_RATES]; /* Max power for A band (SROM) */ ++ int8 txpwr_antgain[2]; /* Ant gain for each band - from SROM */ ++ uint8 txpwr_est_Pout_gofdm; /* Pwr estimate for 2.4 OFDM */ ++} tx_power_legacy_t; ++ ++#define WL_TX_POWER_RATES_LEGACY 45 ++#define WL_TX_POWER_MCS20_FIRST 12 ++#define WL_TX_POWER_MCS20_NUM 16 ++#define WL_TX_POWER_MCS40_FIRST 28 ++#define WL_TX_POWER_MCS40_NUM 17 ++ ++typedef struct { ++ uint32 flags; ++ chanspec_t chanspec; /* txpwr report for this channel */ ++ chanspec_t local_chanspec; /* channel on which we are associated */ ++ uint8 local_max; /* local max according to the AP */ ++ uint8 local_constraint; /* local constraint according to the AP */ ++ int8 antgain[2]; /* Ant gain for each band - from SROM */ ++ uint8 rf_cores; /* count of RF Cores being reported */ ++ uint8 est_Pout[4]; /* Latest tx power out estimate per RF ++ * chain without adjustment ++ */ ++ uint8 est_Pout_cck; /* Latest CCK tx power out estimate */ ++ uint8 user_limit[WL_TX_POWER_RATES_LEGACY]; /* User limit */ ++ uint8 reg_limit[WL_TX_POWER_RATES_LEGACY]; /* Regulatory power limit */ ++ uint8 board_limit[WL_TX_POWER_RATES_LEGACY]; /* Max power board can support (SROM) */ ++ uint8 target[WL_TX_POWER_RATES_LEGACY]; /* Latest target power */ ++} tx_power_legacy2_t; ++ ++/* TX Power index defines */ ++#define WL_NUM_RATES_CCK 4 /* 1, 2, 5.5, 11 Mbps */ ++#define WL_NUM_RATES_OFDM 8 /* 6, 9, 12, 18, 24, 36, 48, 54 Mbps SISO/CDD */ ++#define WL_NUM_RATES_MCS_1STREAM 8 /* MCS 0-7 1-stream rates - SISO/CDD/STBC/MCS */ ++#define WL_NUM_RATES_EXTRA_VHT 2 /* Additional VHT 11AC rates */ ++#define WL_NUM_RATES_VHT 10 ++#define WL_NUM_RATES_MCS32 1 ++ ++#define WLC_NUM_RATES_CCK WL_NUM_RATES_CCK ++#define WLC_NUM_RATES_OFDM WL_NUM_RATES_OFDM ++#define WLC_NUM_RATES_MCS_1_STREAM WL_NUM_RATES_MCS_1STREAM ++#define WLC_NUM_RATES_MCS_2_STREAM WL_NUM_RATES_MCS_1STREAM ++#define WLC_NUM_RATES_MCS32 WL_NUM_RATES_MCS32 ++#define WL_TX_POWER_CCK_NUM WL_NUM_RATES_CCK ++#define WL_TX_POWER_OFDM_NUM WL_NUM_RATES_OFDM ++#define WL_TX_POWER_MCS_1_STREAM_NUM WL_NUM_RATES_MCS_1STREAM ++#define WL_TX_POWER_MCS_2_STREAM_NUM WL_NUM_RATES_MCS_1STREAM ++#define WL_TX_POWER_MCS_32_NUM WL_NUM_RATES_MCS32 ++ ++#define WL_NUM_2x2_ELEMENTS 4 ++#define WL_NUM_3x3_ELEMENTS 6 ++ ++typedef struct txppr { ++ /* start of 20MHz tx power limits */ ++ uint8 b20_1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ ++ uint8 b20_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */ ++ uint8 b20_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */ ++ ++ uint8 b20_1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ ++ uint8 b20_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ ++ uint8 b20_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */ ++ uint8 b20_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ ++ uint8 b20_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */ ++ ++ uint8 b20_1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ ++ uint8 b20_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ ++ uint8 b20_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */ ++ uint8 b20_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ ++ uint8 b20_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */ ++ uint8 b20_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */ ++ ++ uint8 b20_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */ ++ uint8 b20_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */ ++ uint8 b20_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */ ++ uint8 b20_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */ ++ uint8 b20_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */ ++ uint8 b20_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */ ++ uint8 b20_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */ ++ uint8 b20_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */ ++ ++ /* start of 40MHz tx power limits */ ++ uint8 b40_dummy1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ ++ uint8 b40_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */ ++ uint8 b40_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */ ++ ++ uint8 b40_dummy1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ ++ uint8 b40_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ ++ uint8 b40_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */ ++ uint8 b40_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ ++ uint8 b40_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */ ++ ++ uint8 b40_dummy1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ ++ uint8 b40_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ ++ uint8 b40_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */ ++ uint8 b40_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ ++ uint8 b40_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */ ++ uint8 b40_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */ ++ ++ uint8 b40_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */ ++ uint8 b40_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */ ++ uint8 b40_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */ ++ uint8 b40_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */ ++ uint8 b40_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */ ++ uint8 b40_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */ ++ uint8 b40_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */ ++ uint8 b40_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */ ++ ++ /* start of 20in40MHz tx power limits */ ++ uint8 b20in40_1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ ++ uint8 b20in40_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */ ++ uint8 b20in40_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */ ++ ++ uint8 b20in40_1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ ++ uint8 b20in40_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ ++ uint8 b20in40_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */ ++ uint8 b20in40_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ ++ uint8 b20in40_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */ ++ ++ uint8 b20in40_1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ ++ uint8 b20in40_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* 20 in 40 MHz Legacy OFDM CDD */ ++ uint8 b20in40_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */ ++ uint8 b20in40_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ ++ uint8 b20in40_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */ ++ uint8 b20in40_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */ ++ ++ uint8 b20in40_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */ ++ uint8 b20in40_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */ ++ uint8 b20in40_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */ ++ uint8 b20in40_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */ ++ uint8 b20in40_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */ ++ uint8 b20in40_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */ ++ uint8 b20in40_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */ ++ uint8 b20in40_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */ ++ ++ /* start of 80MHz tx power limits */ ++ uint8 b80_dummy1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ ++ uint8 b80_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */ ++ uint8 b80_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */ ++ ++ uint8 b80_dummy1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ ++ uint8 b80_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ ++ uint8 b80_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */ ++ uint8 b80_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ ++ uint8 b80_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */ ++ ++ uint8 b80_dummy1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ ++ uint8 b80_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ ++ uint8 b80_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */ ++ uint8 b80_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ ++ uint8 b80_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */ ++ uint8 b80_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */ ++ ++ uint8 b80_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */ ++ uint8 b80_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */ ++ uint8 b80_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */ ++ uint8 b80_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */ ++ uint8 b80_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */ ++ uint8 b80_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */ ++ uint8 b80_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */ ++ uint8 b80_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */ ++ ++ /* start of 20in80MHz tx power limits */ ++ uint8 b20in80_1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ ++ uint8 b20in80_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */ ++ uint8 b20in80_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */ ++ ++ uint8 b20in80_1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ ++ uint8 b20in80_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ ++ uint8 b20in80_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */ ++ uint8 b20in80_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ ++ uint8 b20in80_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */ ++ ++ uint8 b20in80_1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ ++ uint8 b20in80_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ ++ uint8 b20in80_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */ ++ uint8 b20in80_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ ++ uint8 b20in80_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */ ++ uint8 b20in80_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */ ++ ++ uint8 b20in80_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */ ++ uint8 b20in80_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */ ++ uint8 b20in80_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */ ++ uint8 b20in80_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */ ++ uint8 b20in80_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */ ++ uint8 b20in80_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */ ++ uint8 b20in80_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */ ++ uint8 b20in80_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */ ++ ++ /* start of 40in80MHz tx power limits */ ++ uint8 b40in80_dummy1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ ++ uint8 b40in80_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */ ++ uint8 b40in80_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */ ++ ++ uint8 b40in80_dummy1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ ++ uint8 b40in80_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ ++ uint8 b40in80_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */ ++ uint8 b40in80_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ ++ uint8 b40in80_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */ ++ ++ uint8 b40in80_dummy1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ ++ uint8 b40in80_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* MHz Legacy OFDM CDD */ ++ uint8 b40in80_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */ ++ uint8 b40in80_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ ++ uint8 b40in80_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */ ++ uint8 b40in80_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */ ++ ++ uint8 b40in80_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */ ++ uint8 b40in80_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */ ++ uint8 b40in80_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */ ++ uint8 b40in80_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */ ++ uint8 b40in80_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */ ++ uint8 b40in80_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */ ++ uint8 b40in80_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */ ++ uint8 b40in80_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */ ++ ++ uint8 mcs32; /* C_CHECK - THIS NEEDS TO BE REMOVED THROUGHOUT THE CODE */ ++} txppr_t; ++ ++/* 20MHz */ ++#define WL_TX_POWER_CCK_FIRST OFFSETOF(txppr_t, b20_1x1dsss) ++#define WL_TX_POWER_OFDM20_FIRST OFFSETOF(txppr_t, b20_1x1ofdm) ++#define WL_TX_POWER_MCS20_SISO_FIRST OFFSETOF(txppr_t, b20_1x1mcs0) ++#define WL_TX_POWER_20_S1x1_FIRST OFFSETOF(txppr_t, b20_1x1mcs0) ++ ++#define WL_TX_POWER_CCK_CDD_S1x2_FIRST OFFSETOF(txppr_t, b20_1x2dsss) ++#define WL_TX_POWER_OFDM20_CDD_FIRST OFFSETOF(txppr_t, b20_1x2cdd_ofdm) ++#define WL_TX_POWER_MCS20_CDD_FIRST OFFSETOF(txppr_t, b20_1x2cdd_mcs0) ++#define WL_TX_POWER_20_S1x2_FIRST OFFSETOF(txppr_t, b20_1x2cdd_mcs0) ++#define WL_TX_POWER_MCS20_STBC_FIRST OFFSETOF(txppr_t, b20_2x2stbc_mcs0) ++#define WL_TX_POWER_MCS20_SDM_FIRST OFFSETOF(txppr_t, b20_2x2sdm_mcs8) ++#define WL_TX_POWER_20_S2x2_FIRST OFFSETOF(txppr_t, b20_2x2sdm_mcs8) ++ ++#define WL_TX_POWER_CCK_CDD_S1x3_FIRST OFFSETOF(txppr_t, b20_1x3dsss) ++#define WL_TX_POWER_OFDM20_CDD_S1x3_FIRST OFFSETOF(txppr_t, b20_1x3cdd_ofdm) ++#define WL_TX_POWER_20_S1x3_FIRST OFFSETOF(txppr_t, b20_1x3cdd_mcs0) ++#define WL_TX_POWER_20_STBC_S2x3_FIRST OFFSETOF(txppr_t, b20_2x3stbc_mcs0) ++#define WL_TX_POWER_20_S2x3_FIRST OFFSETOF(txppr_t, b20_2x3sdm_mcs8) ++#define WL_TX_POWER_20_S3x3_FIRST OFFSETOF(txppr_t, b20_3x3sdm_mcs16) ++ ++#define WL_TX_POWER_20_S1X1_VHT OFFSETOF(txppr_t, b20_1x1vht) ++#define WL_TX_POWER_20_S1X2_CDD_VHT OFFSETOF(txppr_t, b20_1x2cdd_vht) ++#define WL_TX_POWER_20_S2X2_STBC_VHT OFFSETOF(txppr_t, b20_2x2stbc_vht) ++#define WL_TX_POWER_20_S2X2_VHT OFFSETOF(txppr_t, b20_2x2sdm_vht) ++#define WL_TX_POWER_20_S1X3_CDD_VHT OFFSETOF(txppr_t, b20_1x3cdd_vht) ++#define WL_TX_POWER_20_S2X3_STBC_VHT OFFSETOF(txppr_t, b20_2x3stbc_vht) ++#define WL_TX_POWER_20_S2X3_VHT OFFSETOF(txppr_t, b20_2x3sdm_vht) ++#define WL_TX_POWER_20_S3X3_VHT OFFSETOF(txppr_t, b20_3x3sdm_vht) ++ ++/* 40MHz */ ++#define WL_TX_POWER_40_DUMMY_CCK_FIRST OFFSETOF(txppr_t, b40_dummy1x1dsss) ++#define WL_TX_POWER_OFDM40_FIRST OFFSETOF(txppr_t, b40_1x1ofdm) ++#define WL_TX_POWER_MCS40_SISO_FIRST OFFSETOF(txppr_t, b40_1x1mcs0) ++#define WL_TX_POWER_40_S1x1_FIRST OFFSETOF(txppr_t, b40_1x1mcs0) ++ ++#define WL_TX_POWER_40_DUMMY_CCK_CDD_S1x2_FIRST OFFSETOF(txppr_t, b40_dummy1x2dsss) ++#define WL_TX_POWER_OFDM40_CDD_FIRST OFFSETOF(txppr_t, b40_1x2cdd_ofdm) ++#define WL_TX_POWER_MCS40_CDD_FIRST OFFSETOF(txppr_t, b40_1x2cdd_mcs0) ++#define WL_TX_POWER_40_S1x2_FIRST OFFSETOF(txppr_t, b40_1x2cdd_mcs0) ++#define WL_TX_POWER_MCS40_STBC_FIRST OFFSETOF(txppr_t, b40_2x2stbc_mcs0) ++#define WL_TX_POWER_MCS40_SDM_FIRST OFFSETOF(txppr_t, b40_2x2sdm_mcs8) ++#define WL_TX_POWER_40_S2x2_FIRST OFFSETOF(txppr_t, b40_2x2sdm_mcs8) ++ ++#define WL_TX_POWER_40_DUMMY_CCK_CDD_S1x3_FIRST OFFSETOF(txppr_t, b40_dummy1x3dsss) ++#define WL_TX_POWER_OFDM40_CDD_S1x3_FIRST OFFSETOF(txppr_t, b40_1x3cdd_ofdm) ++#define WL_TX_POWER_40_S1x3_FIRST OFFSETOF(txppr_t, b40_1x3cdd_mcs0) ++#define WL_TX_POWER_40_STBC_S2x3_FIRST OFFSETOF(txppr_t, b40_2x3stbc_mcs0) ++#define WL_TX_POWER_40_S2x3_FIRST OFFSETOF(txppr_t, b40_2x3sdm_mcs8) ++#define WL_TX_POWER_40_S3x3_FIRST OFFSETOF(txppr_t, b40_3x3sdm_mcs16) ++ ++#define WL_TX_POWER_40_S1X1_VHT OFFSETOF(txppr_t, b40_1x1vht) ++#define WL_TX_POWER_40_S1X2_CDD_VHT OFFSETOF(txppr_t, b40_1x2cdd_vht) ++#define WL_TX_POWER_40_S2X2_STBC_VHT OFFSETOF(txppr_t, b40_2x2stbc_vht) ++#define WL_TX_POWER_40_S2X2_VHT OFFSETOF(txppr_t, b40_2x2sdm_vht) ++#define WL_TX_POWER_40_S1X3_CDD_VHT OFFSETOF(txppr_t, b40_1x3cdd_vht) ++#define WL_TX_POWER_40_S2X3_STBC_VHT OFFSETOF(txppr_t, b40_2x3stbc_vht) ++#define WL_TX_POWER_40_S2X3_VHT OFFSETOF(txppr_t, b40_2x3sdm_vht) ++#define WL_TX_POWER_40_S3X3_VHT OFFSETOF(txppr_t, b40_3x3sdm_vht) ++ ++/* 20 in 40MHz */ ++#define WL_TX_POWER_20UL_CCK_FIRST OFFSETOF(txppr_t, b20in40_1x1dsss) ++#define WL_TX_POWER_20UL_OFDM_FIRST OFFSETOF(txppr_t, b20in40_1x1ofdm) ++#define WL_TX_POWER_20UL_S1x1_FIRST OFFSETOF(txppr_t, b20in40_1x1mcs0) ++ ++#define WL_TX_POWER_CCK_20U_CDD_S1x2_FIRST OFFSETOF(txppr_t, b20in40_1x2dsss) ++#define WL_TX_POWER_20UL_OFDM_CDD_FIRST OFFSETOF(txppr_t, b20in40_1x2cdd_ofdm) ++#define WL_TX_POWER_20UL_S1x2_FIRST OFFSETOF(txppr_t, b20in40_1x2cdd_mcs0) ++#define WL_TX_POWER_20UL_STBC_S2x2_FIRST OFFSETOF(txppr_t, b20in40_2x2stbc_mcs0) ++#define WL_TX_POWER_20UL_S2x2_FIRST OFFSETOF(txppr_t, b20in40_2x2sdm_mcs8) ++ ++#define WL_TX_POWER_CCK_20U_CDD_S1x3_FIRST OFFSETOF(txppr_t, b20in40_1x3dsss) ++#define WL_TX_POWER_20UL_OFDM_CDD_S1x3_FIRST OFFSETOF(txppr_t, b20in40_1x3cdd_ofdm) ++#define WL_TX_POWER_20UL_S1x3_FIRST OFFSETOF(txppr_t, b20in40_1x3cdd_mcs0) ++#define WL_TX_POWER_20UL_STBC_S2x3_FIRST OFFSETOF(txppr_t, b20in40_2x3stbc_mcs0) ++#define WL_TX_POWER_20UL_S2x3_FIRST OFFSETOF(txppr_t, b20in40_2x3sdm_mcs8) ++#define WL_TX_POWER_20UL_S3x3_FIRST OFFSETOF(txppr_t, b20in40_3x3sdm_mcs16) ++ ++#define WL_TX_POWER_20UL_S1X1_VHT OFFSETOF(txppr_t, b20in40_1x1vht) ++#define WL_TX_POWER_20UL_S1X2_CDD_VHT OFFSETOF(txppr_t, b20in40_1x2cdd_vht) ++#define WL_TX_POWER_20UL_S2X2_STBC_VHT OFFSETOF(txppr_t, b20in40_2x2stbc_vht) ++#define WL_TX_POWER_20UL_S2X2_VHT OFFSETOF(txppr_t, b20in40_2x2sdm_vht) ++#define WL_TX_POWER_20UL_S1X3_CDD_VHT OFFSETOF(txppr_t, b20in40_1x3cdd_vht) ++#define WL_TX_POWER_20UL_S2X3_STBC_VHT OFFSETOF(txppr_t, b20in40_2x3stbc_vht) ++#define WL_TX_POWER_20UL_S2X3_VHT OFFSETOF(txppr_t, b20in40_2x3sdm_vht) ++#define WL_TX_POWER_20UL_S3X3_VHT OFFSETOF(txppr_t, b20in40_3x3sdm_vht) ++ ++/* 80MHz */ ++#define WL_TX_POWER_80_DUMMY_CCK_FIRST OFFSETOF(txppr_t, b80_dummy1x1dsss) ++#define WL_TX_POWER_OFDM80_FIRST OFFSETOF(txppr_t, b80_1x1ofdm) ++#define WL_TX_POWER_MCS80_SISO_FIRST OFFSETOF(txppr_t, b80_1x1mcs0) ++#define WL_TX_POWER_80_S1x1_FIRST OFFSETOF(txppr_t, b80_1x1mcs0) ++ ++#define WL_TX_POWER_80_DUMMY_CCK_CDD_S1x2_FIRST OFFSETOF(txppr_t, b80_dummy1x2dsss) ++#define WL_TX_POWER_OFDM80_CDD_FIRST OFFSETOF(txppr_t, b80_1x2cdd_ofdm) ++#define WL_TX_POWER_MCS80_CDD_FIRST OFFSETOF(txppr_t, b80_1x2cdd_mcs0) ++#define WL_TX_POWER_80_S1x2_FIRST OFFSETOF(txppr_t, b80_1x2cdd_mcs0) ++#define WL_TX_POWER_MCS80_STBC_FIRST OFFSETOF(txppr_t, b80_2x2stbc_mcs0) ++#define WL_TX_POWER_MCS80_SDM_FIRST OFFSETOF(txppr_t, b80_2x2sdm_mcs8) ++#define WL_TX_POWER_80_S2x2_FIRST OFFSETOF(txppr_t, b80_2x2sdm_mcs8) ++ ++#define WL_TX_POWER_80_DUMMY_CCK_CDD_S1x3_FIRST OFFSETOF(txppr_t, b80_dummy1x3dsss) ++#define WL_TX_POWER_OFDM80_CDD_S1x3_FIRST OFFSETOF(txppr_t, b80_1x3cdd_ofdm) ++#define WL_TX_POWER_80_S1x3_FIRST OFFSETOF(txppr_t, b80_1x3cdd_mcs0) ++#define WL_TX_POWER_80_STBC_S2x3_FIRST OFFSETOF(txppr_t, b80_2x3stbc_mcs0) ++#define WL_TX_POWER_80_S2x3_FIRST OFFSETOF(txppr_t, b80_2x3sdm_mcs8) ++#define WL_TX_POWER_80_S3x3_FIRST OFFSETOF(txppr_t, b80_3x3sdm_mcs16) ++ ++#define WL_TX_POWER_80_S1X1_VHT OFFSETOF(txppr_t, b80_1x1vht) ++#define WL_TX_POWER_80_S1X2_CDD_VHT OFFSETOF(txppr_t, b80_1x2cdd_vht) ++#define WL_TX_POWER_80_S2X2_STBC_VHT OFFSETOF(txppr_t, b80_2x2stbc_vht) ++#define WL_TX_POWER_80_S2X2_VHT OFFSETOF(txppr_t, b80_2x2sdm_vht) ++#define WL_TX_POWER_80_S1X3_CDD_VHT OFFSETOF(txppr_t, b80_1x3cdd_vht) ++#define WL_TX_POWER_80_S2X3_STBC_VHT OFFSETOF(txppr_t, b80_2x3stbc_vht) ++#define WL_TX_POWER_80_S2X3_VHT OFFSETOF(txppr_t, b80_2x3sdm_vht) ++#define WL_TX_POWER_80_S3X3_VHT OFFSETOF(txppr_t, b80_3x3sdm_vht) ++ ++/* 20 in 80MHz */ ++#define WL_TX_POWER_20UUL_CCK_FIRST OFFSETOF(txppr_t, b20in80_1x1dsss) ++#define WL_TX_POWER_20UUL_OFDM_FIRST OFFSETOF(txppr_t, b20in80_1x1ofdm) ++#define WL_TX_POWER_20UUL_S1x1_FIRST OFFSETOF(txppr_t, b20in80_1x1mcs0) ++ ++#define WL_TX_POWER_CCK_20UU_CDD_S1x2_FIRST OFFSETOF(txppr_t, b20in80_1x2dsss) ++#define WL_TX_POWER_20UUL_OFDM_CDD_FIRST OFFSETOF(txppr_t, b20in80_1x2cdd_ofdm) ++#define WL_TX_POWER_20UUL_S1x2_FIRST OFFSETOF(txppr_t, b20in80_1x2cdd_mcs0) ++#define WL_TX_POWER_20UUL_STBC_S2x2_FIRST OFFSETOF(txppr_t, b20in80_2x2stbc_mcs0) ++#define WL_TX_POWER_20UUL_S2x2_FIRST OFFSETOF(txppr_t, b20in80_2x2sdm_mcs8) ++ ++#define WL_TX_POWER_CCK_20UU_CDD_S1x3_FIRST OFFSETOF(txppr_t, b20in80_1x3dsss) ++#define WL_TX_POWER_20UUL_OFDM_CDD_S1x3_FIRST OFFSETOF(txppr_t, b20in80_1x3cdd_ofdm) ++#define WL_TX_POWER_20UUL_S1x3_FIRST OFFSETOF(txppr_t, b20in80_1x3cdd_mcs0) ++#define WL_TX_POWER_20UUL_STBC_S2x3_FIRST OFFSETOF(txppr_t, b20in80_2x3stbc_mcs0) ++#define WL_TX_POWER_20UUL_S2x3_FIRST OFFSETOF(txppr_t, b20in80_2x3sdm_mcs8) ++#define WL_TX_POWER_20UUL_S3x3_FIRST OFFSETOF(txppr_t, b20in80_3x3sdm_mcs16) ++ ++#define WL_TX_POWER_20UUL_S1X1_VHT OFFSETOF(txppr_t, b20in80_1x1vht) ++#define WL_TX_POWER_20UUL_S1X2_CDD_VHT OFFSETOF(txppr_t, b20in80_1x2cdd_vht) ++#define WL_TX_POWER_20UUL_S2X2_STBC_VHT OFFSETOF(txppr_t, b20in80_2x2stbc_vht) ++#define WL_TX_POWER_20UUL_S2X2_VHT OFFSETOF(txppr_t, b20in80_2x2sdm_vht) ++#define WL_TX_POWER_20UUL_S1X3_CDD_VHT OFFSETOF(txppr_t, b20in80_1x3cdd_vht) ++#define WL_TX_POWER_20UUL_S2X3_STBC_VHT OFFSETOF(txppr_t, b20in80_2x3stbc_vht) ++#define WL_TX_POWER_20UUL_S2X3_VHT OFFSETOF(txppr_t, b20in80_2x3sdm_vht) ++#define WL_TX_POWER_20UUL_S3X3_VHT OFFSETOF(txppr_t, b20in80_3x3sdm_vht) ++ ++/* 40 in 80MHz */ ++#define WL_TX_POWER_40UUL_DUMMY_CCK_FIRST OFFSETOF(txppr_t, b40in80_dummy1x1dsss) ++#define WL_TX_POWER_40UUL_OFDM_FIRST OFFSETOF(txppr_t, b40in80_1x1ofdm) ++#define WL_TX_POWER_40UUL_S1x1_FIRST OFFSETOF(txppr_t, b40in80_1x1mcs0) ++ ++#define WL_TX_POWER_CCK_40UU_DUMMY_CDD_S1x2_FIRST OFFSETOF(txppr_t, b40in80_dummy1x2dsss) ++#define WL_TX_POWER_40UUL_OFDM_CDD_FIRST OFFSETOF(txppr_t, b40in80_1x2cdd_ofdm) ++#define WL_TX_POWER_40UUL_S1x2_FIRST OFFSETOF(txppr_t, b40in80_1x2cdd_mcs0) ++#define WL_TX_POWER_40UUL_STBC_S2x2_FIRST OFFSETOF(txppr_t, b40in80_2x2stbc_mcs0) ++#define WL_TX_POWER_40UUL_S2x2_FIRST OFFSETOF(txppr_t, b40in80_2x2sdm_mcs8) ++ ++#define WL_TX_POWER_CCK_40UU_DUMMY_CDD_S1x3_FIRST OFFSETOF(txppr_t, b40in80_dummy1x3dsss) ++#define WL_TX_POWER_40UUL_OFDM_CDD_S1x3_FIRST OFFSETOF(txppr_t, b40in80_1x3cdd_ofdm) ++#define WL_TX_POWER_40UUL_S1x3_FIRST OFFSETOF(txppr_t, b40in80_1x3cdd_mcs0) ++#define WL_TX_POWER_40UUL_STBC_S2x3_FIRST OFFSETOF(txppr_t, b40in80_2x3stbc_mcs0) ++#define WL_TX_POWER_40UUL_S2x3_FIRST OFFSETOF(txppr_t, b40in80_2x3sdm_mcs8) ++#define WL_TX_POWER_40UUL_S3x3_FIRST OFFSETOF(txppr_t, b40in80_3x3sdm_mcs16) ++ ++#define WL_TX_POWER_40UUL_S1X1_VHT OFFSETOF(txppr_t, b40in80_1x1vht) ++#define WL_TX_POWER_40UUL_S1X2_CDD_VHT OFFSETOF(txppr_t, b40in80_1x2cdd_vht) ++#define WL_TX_POWER_40UUL_S2X2_STBC_VHT OFFSETOF(txppr_t, b40in80_2x2stbc_vht) ++#define WL_TX_POWER_40UUL_S2X2_VHT OFFSETOF(txppr_t, b40in80_2x2sdm_vht) ++#define WL_TX_POWER_40UUL_S1X3_CDD_VHT OFFSETOF(txppr_t, b40in80_1x3cdd_vht) ++#define WL_TX_POWER_40UUL_S2X3_STBC_VHT OFFSETOF(txppr_t, b40in80_2x3stbc_vht) ++#define WL_TX_POWER_40UUL_S2X3_VHT OFFSETOF(txppr_t, b40in80_2x3sdm_vht) ++#define WL_TX_POWER_40UUL_S3X3_VHT OFFSETOF(txppr_t, b40in80_3x3sdm_vht) ++ ++#define WL_TX_POWER_MCS_32 OFFSETOF(txppr_t, mcs32) /* C_CHECK remove later */ ++ ++#define WL_TX_POWER_RATES sizeof(struct txppr) ++ ++/* sslpnphy specifics */ ++#define WL_TX_POWER_MCS20_SISO_FIRST_SSN WL_TX_POWER_MCS20_SISO_FIRST ++#define WL_TX_POWER_MCS40_SISO_FIRST_SSN WL_TX_POWER_MCS40_SISO_FIRST ++ ++typedef struct { ++ uint16 ver; /* version of this struct */ ++ uint16 len; /* length in bytes of this structure */ ++ uint32 flags; ++ chanspec_t chanspec; /* txpwr report for this channel */ ++ chanspec_t local_chanspec; /* channel on which we are associated */ ++ uint8 ppr[WL_TX_POWER_RATES]; /* Latest target power */ ++} wl_txppr_t; ++ ++#define WL_TXPPR_VERSION 0 ++#define WL_TXPPR_LENGTH (sizeof(wl_txppr_t)) ++#define TX_POWER_T_VERSION 43 ++ ++/* Defines used with channel_bandwidth for curpower */ ++#define WL_BW_20MHZ 0 ++#define WL_BW_40MHZ 1 ++#define WL_BW_80MHZ 2 ++ ++/* tx_power_t.flags bits */ ++#ifdef PPR_API ++#define WL_TX_POWER2_F_ENABLED 1 ++#define WL_TX_POWER2_F_HW 2 ++#define WL_TX_POWER2_F_MIMO 4 ++#define WL_TX_POWER2_F_SISO 8 ++#define WL_TX_POWER2_F_HT 0x10 ++#else ++#define WL_TX_POWER_F_ENABLED 1 ++#define WL_TX_POWER_F_HW 2 ++#define WL_TX_POWER_F_MIMO 4 ++#define WL_TX_POWER_F_SISO 8 ++#define WL_TX_POWER_F_HT 0x10 ++#endif ++ ++typedef struct { ++ uint32 flags; ++ chanspec_t chanspec; /* txpwr report for this channel */ ++ chanspec_t local_chanspec; /* channel on which we are associated */ ++ uint8 local_max; /* local max according to the AP */ ++ uint8 local_constraint; /* local constraint according to the AP */ ++ int8 antgain[2]; /* Ant gain for each band - from SROM */ ++ uint8 rf_cores; /* count of RF Cores being reported */ ++ uint8 est_Pout[4]; /* Latest tx power out estimate per RF chain */ ++ uint8 est_Pout_act[4]; /* Latest tx power out estimate per RF chain w/o adjustment */ ++ uint8 est_Pout_cck; /* Latest CCK tx power out estimate */ ++ uint8 tx_power_max[4]; /* Maximum target power among all rates */ ++ uint tx_power_max_rate_ind[4]; /* Index of the rate with the max target power */ ++ uint8 user_limit[WL_TX_POWER_RATES]; /* User limit */ ++ int8 board_limit[WL_TX_POWER_RATES]; /* Max power board can support (SROM) */ ++ int8 target[WL_TX_POWER_RATES]; /* Latest target power */ ++ int8 clm_limits[WL_NUMRATES]; /* regulatory limits - 20, 40 or 80MHz */ ++ int8 clm_limits_subchan1[WL_NUMRATES]; /* regulatory limits - 20in40 or 40in80 */ ++ int8 clm_limits_subchan2[WL_NUMRATES]; /* regulatory limits - 20in80MHz */ ++ int8 sar; /* SAR limit for display by wl executable */ ++ int8 channel_bandwidth; /* 20, 40 or 80 MHz bandwidth? */ ++ uint8 version; /* Version of the data format wlu <--> driver */ ++ uint8 display_core; /* Displayed curpower core */ ++#ifdef PPR_API ++} tx_power_new_t; ++#else ++} tx_power_t; ++#endif ++ ++typedef struct tx_inst_power { ++ uint8 txpwr_est_Pout[2]; /* Latest estimate for 2.4 and 5 Ghz */ ++ uint8 txpwr_est_Pout_gofdm; /* Pwr estimate for 2.4 OFDM */ ++} tx_inst_power_t; ++ ++ ++typedef struct { ++ uint32 flags; ++ chanspec_t chanspec; /* txpwr report for this channel */ ++ chanspec_t local_chanspec; /* channel on which we are associated */ ++ uint8 local_max; /* local max according to the AP */ ++ uint8 local_constraint; /* local constraint according to the AP */ ++ int8 antgain[2]; /* Ant gain for each band - from SROM */ ++ uint8 rf_cores; /* count of RF Cores being reported */ ++ uint8 est_Pout[4]; /* Latest tx power out estimate per RF chain */ ++ uint8 est_Pout_act[4]; /* Latest tx power out estimate per RF chain ++ * without adjustment ++ */ ++ uint8 est_Pout_cck; /* Latest CCK tx power out estimate */ ++ uint8 tx_power_max[4]; /* Maximum target power among all rates */ ++ uint tx_power_max_rate_ind[4]; /* Index of the rate with the max target power */ ++ txppr_t user_limit; /* User limit */ ++ txppr_t reg_limit; /* Regulatory power limit */ ++ txppr_t board_limit; /* Max power board can support (SROM) */ ++ txppr_t target; /* Latest target power */ ++} wl_txpwr_t; ++ ++#define WL_NUM_TXCHAIN_MAX 4 ++typedef struct wl_txchain_pwr_offsets { ++ int8 offset[WL_NUM_TXCHAIN_MAX]; /* quarter dBm signed offset for each chain */ ++} wl_txchain_pwr_offsets_t; ++ ++/* 802.11h measurement types */ ++#define WLC_MEASURE_TPC 1 ++#define WLC_MEASURE_CHANNEL_BASIC 2 ++#define WLC_MEASURE_CHANNEL_CCA 3 ++#define WLC_MEASURE_CHANNEL_RPI 4 ++ ++/* regulatory enforcement levels */ ++#define SPECT_MNGMT_OFF 0 /* both 11h and 11d disabled */ ++#define SPECT_MNGMT_LOOSE_11H 1 /* allow non-11h APs in scan lists */ ++#define SPECT_MNGMT_STRICT_11H 2 /* prune out non-11h APs from scan list */ ++#define SPECT_MNGMT_STRICT_11D 3 /* switch to 802.11D mode */ ++/* SPECT_MNGMT_LOOSE_11H_D - same as SPECT_MNGMT_LOOSE with the exception that Country IE ++ * adoption is done regardless of capability spectrum_management ++ */ ++#define SPECT_MNGMT_LOOSE_11H_D 4 /* operation defined above */ ++ ++#define WL_CHAN_VALID_HW (1 << 0) /* valid with current HW */ ++#define WL_CHAN_VALID_SW (1 << 1) /* valid with current country setting */ ++#define WL_CHAN_BAND_5G (1 << 2) /* 5GHz-band channel */ ++#define WL_CHAN_RADAR (1 << 3) /* radar sensitive channel */ ++#define WL_CHAN_INACTIVE (1 << 4) /* temporarily inactive due to radar */ ++#define WL_CHAN_PASSIVE (1 << 5) /* channel is in passive mode */ ++#define WL_CHAN_RESTRICTED (1 << 6) /* restricted use channel */ ++ ++/* BTC mode used by "btc_mode" iovar */ ++#define WL_BTC_DISABLE 0 /* disable BT coexistence */ ++#define WL_BTC_FULLTDM 1 /* full TDM COEX */ ++#define WL_BTC_ENABLE 1 /* full TDM COEX to maintain backward compatiblity */ ++#define WL_BTC_PREMPT 2 /* full TDM COEX with preemption */ ++#define WL_BTC_LITE 3 /* light weight coex for large isolation platform */ ++#define WL_BTC_PARALLEL 4 /* BT and WLAN run in parallel with separate antenna */ ++#define WL_BTC_HYBRID 5 /* hybrid coex, only ack is allowed to transmit in BT slot */ ++#define WL_BTC_DEFAULT 8 /* set the default mode for the device */ ++#define WL_INF_BTC_DISABLE 0 ++#define WL_INF_BTC_ENABLE 1 ++#define WL_INF_BTC_AUTO 3 ++ ++/* BTC wire used by "btc_wire" iovar */ ++#define WL_BTC_DEFWIRE 0 /* use default wire setting */ ++#define WL_BTC_2WIRE 2 /* use 2-wire BTC */ ++#define WL_BTC_3WIRE 3 /* use 3-wire BTC */ ++#define WL_BTC_4WIRE 4 /* use 4-wire BTC */ ++ ++/* BTC flags: BTC configuration that can be set by host */ ++#define WL_BTC_FLAG_PREMPT (1 << 0) ++#define WL_BTC_FLAG_BT_DEF (1 << 1) ++#define WL_BTC_FLAG_ACTIVE_PROT (1 << 2) ++#define WL_BTC_FLAG_SIM_RSP (1 << 3) ++#define WL_BTC_FLAG_PS_PROTECT (1 << 4) ++#define WL_BTC_FLAG_SIM_TX_LP (1 << 5) ++#define WL_BTC_FLAG_ECI (1 << 6) ++#define WL_BTC_FLAG_LIGHT (1 << 7) ++#define WL_BTC_FLAG_PARALLEL (1 << 8) ++#endif /* !defined(LINUX_POSTMOGRIFY_REMOVAL) */ ++ ++/* Message levels */ ++#define WL_ERROR_VAL 0x00000001 ++#define WL_TRACE_VAL 0x00000002 ++#define WL_PRHDRS_VAL 0x00000004 ++#define WL_PRPKT_VAL 0x00000008 ++#define WL_INFORM_VAL 0x00000010 ++#define WL_TMP_VAL 0x00000020 ++#define WL_OID_VAL 0x00000040 ++#define WL_RATE_VAL 0x00000080 ++#define WL_ASSOC_VAL 0x00000100 ++#define WL_PRUSR_VAL 0x00000200 ++#define WL_PS_VAL 0x00000400 ++#define WL_TXPWR_VAL 0x00000800 /* retired in TOT on 6/10/2009 */ ++#define WL_PORT_VAL 0x00001000 ++#define WL_DUAL_VAL 0x00002000 ++#define WL_WSEC_VAL 0x00004000 ++#define WL_WSEC_DUMP_VAL 0x00008000 ++#define WL_LOG_VAL 0x00010000 ++#define WL_NRSSI_VAL 0x00020000 /* retired in TOT on 6/10/2009 */ ++#define WL_LOFT_VAL 0x00040000 /* retired in TOT on 6/10/2009 */ ++#define WL_REGULATORY_VAL 0x00080000 ++#define WL_PHYCAL_VAL 0x00100000 /* retired in TOT on 6/10/2009 */ ++#define WL_RADAR_VAL 0x00200000 /* retired in TOT on 6/10/2009 */ ++#define WL_MPC_VAL 0x00400000 ++#define WL_APSTA_VAL 0x00800000 ++#define WL_DFS_VAL 0x01000000 ++#define WL_BA_VAL 0x02000000 /* retired in TOT on 6/14/2010 */ ++#define WL_ACI_VAL 0x04000000 ++#define WL_MBSS_VAL 0x04000000 ++#define WL_CAC_VAL 0x08000000 ++#define WL_AMSDU_VAL 0x10000000 ++#define WL_AMPDU_VAL 0x20000000 ++#define WL_FFPLD_VAL 0x40000000 ++ ++/* wl_msg_level is full. For new bits take the next one and AND with ++ * wl_msg_level2 in wl_dbg.h ++ */ ++#define WL_DPT_VAL 0x00000001 ++#define WL_SCAN_VAL 0x00000002 ++#define WL_WOWL_VAL 0x00000004 ++#define WL_COEX_VAL 0x00000008 ++#define WL_RTDC_VAL 0x00000010 ++#define WL_PROTO_VAL 0x00000020 ++#define WL_BTA_VAL 0x00000040 ++#define WL_CHANINT_VAL 0x00000080 ++#define WL_THERMAL_VAL 0x00000100 /* retired in TOT on 6/10/2009 */ ++#define WL_P2P_VAL 0x00000200 ++#define WL_ITFR_VAL 0x00000400 ++#define WL_MCHAN_VAL 0x00000800 ++#define WL_TDLS_VAL 0x00001000 ++#define WL_MCNX_VAL 0x00002000 ++#define WL_PROT_VAL 0x00004000 ++#define WL_PSTA_VAL 0x00008000 ++#define WL_TSO_VAL 0x00010000 ++/* use top-bit for WL_TIME_STAMP_VAL because this is a modifier ++ * rather than a message-type of its own ++ */ ++#define WL_TIMESTAMP_VAL 0x80000000 ++ ++/* max # of leds supported by GPIO (gpio pin# == led index#) */ ++#define WL_LED_NUMGPIO 32 /* gpio 0-31 */ ++ ++/* led per-pin behaviors */ ++#define WL_LED_OFF 0 /* always off */ ++#define WL_LED_ON 1 /* always on */ ++#define WL_LED_ACTIVITY 2 /* activity */ ++#define WL_LED_RADIO 3 /* radio enabled */ ++#define WL_LED_ARADIO 4 /* 5 Ghz radio enabled */ ++#define WL_LED_BRADIO 5 /* 2.4Ghz radio enabled */ ++#define WL_LED_BGMODE 6 /* on if gmode, off if bmode */ ++#define WL_LED_WI1 7 ++#define WL_LED_WI2 8 ++#define WL_LED_WI3 9 ++#define WL_LED_ASSOC 10 /* associated state indicator */ ++#define WL_LED_INACTIVE 11 /* null behavior (clears default behavior) */ ++#define WL_LED_ASSOCACT 12 /* on when associated; blink fast for activity */ ++#define WL_LED_WI4 13 ++#define WL_LED_WI5 14 ++#define WL_LED_BLINKSLOW 15 /* blink slow */ ++#define WL_LED_BLINKMED 16 /* blink med */ ++#define WL_LED_BLINKFAST 17 /* blink fast */ ++#define WL_LED_BLINKCUSTOM 18 /* blink custom */ ++#define WL_LED_BLINKPERIODIC 19 /* blink periodic (custom 1000ms / off 400ms) */ ++#define WL_LED_ASSOC_WITH_SEC 20 /* when connected with security */ ++ /* keep on for 300 sec */ ++#define WL_LED_START_OFF 21 /* off upon boot, could be turned on later */ ++#define WL_LED_NUMBEHAVIOR 22 ++ ++/* led behavior numeric value format */ ++#define WL_LED_BEH_MASK 0x7f /* behavior mask */ ++#define WL_LED_AL_MASK 0x80 /* activelow (polarity) bit */ ++ ++/* maximum channels returned by the get valid channels iovar */ ++#define WL_NUMCHANNELS 64 ++ ++/* max number of chanspecs (used by the iovar to calc. buf space) */ ++#define WL_NUMCHANSPECS 110 ++ ++/* WDS link local endpoint WPA role */ ++#define WL_WDS_WPA_ROLE_AUTH 0 /* authenticator */ ++#define WL_WDS_WPA_ROLE_SUP 1 /* supplicant */ ++#define WL_WDS_WPA_ROLE_AUTO 255 /* auto, based on mac addr value */ ++ ++/* number of bytes needed to define a 128-bit mask for MAC event reporting */ ++#define WL_EVENTING_MASK_LEN 16 ++ ++/* ++ * Join preference iovar value is an array of tuples. Each tuple has a one-byte type, ++ * a one-byte length, and a variable length value. RSSI type tuple must be present ++ * in the array. ++ * ++ * Types are defined in "join preference types" section. ++ * ++ * Length is the value size in octets. It is reserved for WL_JOIN_PREF_WPA type tuple ++ * and must be set to zero. ++ * ++ * Values are defined below. ++ * ++ * 1. RSSI - 2 octets ++ * offset 0: reserved ++ * offset 1: reserved ++ * ++ * 2. WPA - 2 + 12 * n octets (n is # tuples defined below) ++ * offset 0: reserved ++ * offset 1: # of tuples ++ * offset 2: tuple 1 ++ * offset 14: tuple 2 ++ * ... ++ * offset 2 + 12 * (n - 1) octets: tuple n ++ * ++ * struct wpa_cfg_tuple { ++ * uint8 akm[DOT11_OUI_LEN+1]; akm suite ++ * uint8 ucipher[DOT11_OUI_LEN+1]; unicast cipher suite ++ * uint8 mcipher[DOT11_OUI_LEN+1]; multicast cipher suite ++ * }; ++ * ++ * multicast cipher suite can be specified as a specific cipher suite or WL_WPA_ACP_MCS_ANY. ++ * ++ * 3. BAND - 2 octets ++ * offset 0: reserved ++ * offset 1: see "band preference" and "band types" ++ * ++ * 4. BAND RSSI - 2 octets ++ * offset 0: band types ++ * offset 1: +ve RSSI boost balue in dB ++ */ ++ ++/* join preference types */ ++#define WL_JOIN_PREF_RSSI 1 /* by RSSI */ ++#define WL_JOIN_PREF_WPA 2 /* by akm and ciphers */ ++#define WL_JOIN_PREF_BAND 3 /* by 802.11 band */ ++#define WL_JOIN_PREF_RSSI_DELTA 4 /* by 802.11 band only if RSSI delta condition matches */ ++#define WL_JOIN_PREF_TRANS_PREF 5 /* defined by requesting AP */ ++ ++/* band preference */ ++#define WLJP_BAND_ASSOC_PREF 255 /* use what WLC_SET_ASSOC_PREFER ioctl specifies */ ++ ++/* any multicast cipher suite */ ++#define WL_WPA_ACP_MCS_ANY "\x00\x00\x00\x00" ++ ++struct tsinfo_arg { ++ uint8 octets[3]; ++}; ++ ++#define NFIFO 6 /* # tx/rx fifopairs */ ++ ++#define WL_CNT_T_VERSION 8 /* current version of wl_cnt_t struct */ ++ ++typedef struct { ++ uint16 version; /* see definition of WL_CNT_T_VERSION */ ++ uint16 length; /* length of entire structure */ ++ ++ /* transmit stat counters */ ++ uint32 txframe; /* tx data frames */ ++ uint32 txbyte; /* tx data bytes */ ++ uint32 txretrans; /* tx mac retransmits */ ++ uint32 txerror; /* tx data errors (derived: sum of others) */ ++ uint32 txctl; /* tx management frames */ ++ uint32 txprshort; /* tx short preamble frames */ ++ uint32 txserr; /* tx status errors */ ++ uint32 txnobuf; /* tx out of buffers errors */ ++ uint32 txnoassoc; /* tx discard because we're not associated */ ++ uint32 txrunt; /* tx runt frames */ ++ uint32 txchit; /* tx header cache hit (fastpath) */ ++ uint32 txcmiss; /* tx header cache miss (slowpath) */ ++ ++ /* transmit chip error counters */ ++ uint32 txuflo; /* tx fifo underflows */ ++ uint32 txphyerr; /* tx phy errors (indicated in tx status) */ ++ uint32 txphycrs; ++ ++ /* receive stat counters */ ++ uint32 rxframe; /* rx data frames */ ++ uint32 rxbyte; /* rx data bytes */ ++ uint32 rxerror; /* rx data errors (derived: sum of others) */ ++ uint32 rxctl; /* rx management frames */ ++ uint32 rxnobuf; /* rx out of buffers errors */ ++ uint32 rxnondata; /* rx non data frames in the data channel errors */ ++ uint32 rxbadds; /* rx bad DS errors */ ++ uint32 rxbadcm; /* rx bad control or management frames */ ++ uint32 rxfragerr; /* rx fragmentation errors */ ++ uint32 rxrunt; /* rx runt frames */ ++ uint32 rxgiant; /* rx giant frames */ ++ uint32 rxnoscb; /* rx no scb error */ ++ uint32 rxbadproto; /* rx invalid frames */ ++ uint32 rxbadsrcmac; /* rx frames with Invalid Src Mac */ ++ uint32 rxbadda; /* rx frames tossed for invalid da */ ++ uint32 rxfilter; /* rx frames filtered out */ ++ ++ /* receive chip error counters */ ++ uint32 rxoflo; /* rx fifo overflow errors */ ++ uint32 rxuflo[NFIFO]; /* rx dma descriptor underflow errors */ ++ ++ uint32 d11cnt_txrts_off; /* d11cnt txrts value when reset d11cnt */ ++ uint32 d11cnt_rxcrc_off; /* d11cnt rxcrc value when reset d11cnt */ ++ uint32 d11cnt_txnocts_off; /* d11cnt txnocts value when reset d11cnt */ ++ ++ /* misc counters */ ++ uint32 dmade; /* tx/rx dma descriptor errors */ ++ uint32 dmada; /* tx/rx dma data errors */ ++ uint32 dmape; /* tx/rx dma descriptor protocol errors */ ++ uint32 reset; /* reset count */ ++ uint32 tbtt; /* cnts the TBTT int's */ ++ uint32 txdmawar; ++ uint32 pkt_callback_reg_fail; /* callbacks register failure */ ++ ++ /* MAC counters: 32-bit version of d11.h's macstat_t */ ++ uint32 txallfrm; /* total number of frames sent, incl. Data, ACK, RTS, CTS, ++ * Control Management (includes retransmissions) ++ */ ++ uint32 txrtsfrm; /* number of RTS sent out by the MAC */ ++ uint32 txctsfrm; /* number of CTS sent out by the MAC */ ++ uint32 txackfrm; /* number of ACK frames sent out */ ++ uint32 txdnlfrm; /* Not used */ ++ uint32 txbcnfrm; /* beacons transmitted */ ++ uint32 txfunfl[8]; /* per-fifo tx underflows */ ++ uint32 txtplunfl; /* Template underflows (mac was too slow to transmit ACK/CTS ++ * or BCN) ++ */ ++ uint32 txphyerror; /* Transmit phy error, type of error is reported in tx-status for ++ * driver enqueued frames ++ */ ++ uint32 rxfrmtoolong; /* Received frame longer than legal limit (2346 bytes) */ ++ uint32 rxfrmtooshrt; /* Received frame did not contain enough bytes for its frame type */ ++ uint32 rxinvmachdr; /* Either the protocol version != 0 or frame type not ++ * data/control/management ++ */ ++ uint32 rxbadfcs; /* number of frames for which the CRC check failed in the MAC */ ++ uint32 rxbadplcp; /* parity check of the PLCP header failed */ ++ uint32 rxcrsglitch; /* PHY was able to correlate the preamble but not the header */ ++ uint32 rxstrt; /* Number of received frames with a good PLCP ++ * (i.e. passing parity check) ++ */ ++ uint32 rxdfrmucastmbss; /* Number of received DATA frames with good FCS and matching RA */ ++ uint32 rxmfrmucastmbss; /* number of received mgmt frames with good FCS and matching RA */ ++ uint32 rxcfrmucast; /* number of received CNTRL frames with good FCS and matching RA */ ++ uint32 rxrtsucast; /* number of unicast RTS addressed to the MAC (good FCS) */ ++ uint32 rxctsucast; /* number of unicast CTS addressed to the MAC (good FCS) */ ++ uint32 rxackucast; /* number of ucast ACKS received (good FCS) */ ++ uint32 rxdfrmocast; /* number of received DATA frames (good FCS and not matching RA) */ ++ uint32 rxmfrmocast; /* number of received MGMT frames (good FCS and not matching RA) */ ++ uint32 rxcfrmocast; /* number of received CNTRL frame (good FCS and not matching RA) */ ++ uint32 rxrtsocast; /* number of received RTS not addressed to the MAC */ ++ uint32 rxctsocast; /* number of received CTS not addressed to the MAC */ ++ uint32 rxdfrmmcast; /* number of RX Data multicast frames received by the MAC */ ++ uint32 rxmfrmmcast; /* number of RX Management multicast frames received by the MAC */ ++ uint32 rxcfrmmcast; /* number of RX Control multicast frames received by the MAC ++ * (unlikely to see these) ++ */ ++ uint32 rxbeaconmbss; /* beacons received from member of BSS */ ++ uint32 rxdfrmucastobss; /* number of unicast frames addressed to the MAC from ++ * other BSS (WDS FRAME) ++ */ ++ uint32 rxbeaconobss; /* beacons received from other BSS */ ++ uint32 rxrsptmout; /* Number of response timeouts for transmitted frames ++ * expecting a response ++ */ ++ uint32 bcntxcancl; /* transmit beacons canceled due to receipt of beacon (IBSS) */ ++ uint32 rxf0ovfl; /* Number of receive fifo 0 overflows */ ++ uint32 rxf1ovfl; /* Number of receive fifo 1 overflows (obsolete) */ ++ uint32 rxf2ovfl; /* Number of receive fifo 2 overflows (obsolete) */ ++ uint32 txsfovfl; /* Number of transmit status fifo overflows (obsolete) */ ++ uint32 pmqovfl; /* Number of PMQ overflows */ ++ uint32 rxcgprqfrm; /* Number of received Probe requests that made it into ++ * the PRQ fifo ++ */ ++ uint32 rxcgprsqovfl; /* Rx Probe Request Que overflow in the AP */ ++ uint32 txcgprsfail; /* Tx Probe Response Fail. AP sent probe response but did ++ * not get ACK ++ */ ++ uint32 txcgprssuc; /* Tx Probe Response Success (ACK was received) */ ++ uint32 prs_timeout; /* Number of probe requests that were dropped from the PRQ ++ * fifo because a probe response could not be sent out within ++ * the time limit defined in M_PRS_MAXTIME ++ */ ++ uint32 rxnack; /* obsolete */ ++ uint32 frmscons; /* obsolete */ ++ uint32 txnack; /* obsolete */ ++ uint32 txglitch_nack; /* obsolete */ ++ uint32 txburst; /* obsolete */ ++ ++ /* 802.11 MIB counters, pp. 614 of 802.11 reaff doc. */ ++ uint32 txfrag; /* dot11TransmittedFragmentCount */ ++ uint32 txmulti; /* dot11MulticastTransmittedFrameCount */ ++ uint32 txfail; /* dot11FailedCount */ ++ uint32 txretry; /* dot11RetryCount */ ++ uint32 txretrie; /* dot11MultipleRetryCount */ ++ uint32 rxdup; /* dot11FrameduplicateCount */ ++ uint32 txrts; /* dot11RTSSuccessCount */ ++ uint32 txnocts; /* dot11RTSFailureCount */ ++ uint32 txnoack; /* dot11ACKFailureCount */ ++ uint32 rxfrag; /* dot11ReceivedFragmentCount */ ++ uint32 rxmulti; /* dot11MulticastReceivedFrameCount */ ++ uint32 rxcrc; /* dot11FCSErrorCount */ ++ uint32 txfrmsnt; /* dot11TransmittedFrameCount (bogus MIB?) */ ++ uint32 rxundec; /* dot11WEPUndecryptableCount */ ++ ++ /* WPA2 counters (see rxundec for DecryptFailureCount) */ ++ uint32 tkipmicfaill; /* TKIPLocalMICFailures */ ++ uint32 tkipcntrmsr; /* TKIPCounterMeasuresInvoked */ ++ uint32 tkipreplay; /* TKIPReplays */ ++ uint32 ccmpfmterr; /* CCMPFormatErrors */ ++ uint32 ccmpreplay; /* CCMPReplays */ ++ uint32 ccmpundec; /* CCMPDecryptErrors */ ++ uint32 fourwayfail; /* FourWayHandshakeFailures */ ++ uint32 wepundec; /* dot11WEPUndecryptableCount */ ++ uint32 wepicverr; /* dot11WEPICVErrorCount */ ++ uint32 decsuccess; /* DecryptSuccessCount */ ++ uint32 tkipicverr; /* TKIPICVErrorCount */ ++ uint32 wepexcluded; /* dot11WEPExcludedCount */ ++ ++ uint32 txchanrej; /* Tx frames suppressed due to channel rejection */ ++ uint32 psmwds; /* Count PSM watchdogs */ ++ uint32 phywatchdog; /* Count Phy watchdogs (triggered by ucode) */ ++ ++ /* MBSS counters, AP only */ ++ uint32 prq_entries_handled; /* PRQ entries read in */ ++ uint32 prq_undirected_entries; /* which were bcast bss & ssid */ ++ uint32 prq_bad_entries; /* which could not be translated to info */ ++ uint32 atim_suppress_count; /* TX suppressions on ATIM fifo */ ++ uint32 bcn_template_not_ready; /* Template marked in use on send bcn ... */ ++ uint32 bcn_template_not_ready_done; /* ...but "DMA done" interrupt rcvd */ ++ uint32 late_tbtt_dpc; /* TBTT DPC did not happen in time */ ++ ++ /* per-rate receive stat counters */ ++ uint32 rx1mbps; /* packets rx at 1Mbps */ ++ uint32 rx2mbps; /* packets rx at 2Mbps */ ++ uint32 rx5mbps5; /* packets rx at 5.5Mbps */ ++ uint32 rx6mbps; /* packets rx at 6Mbps */ ++ uint32 rx9mbps; /* packets rx at 9Mbps */ ++ uint32 rx11mbps; /* packets rx at 11Mbps */ ++ uint32 rx12mbps; /* packets rx at 12Mbps */ ++ uint32 rx18mbps; /* packets rx at 18Mbps */ ++ uint32 rx24mbps; /* packets rx at 24Mbps */ ++ uint32 rx36mbps; /* packets rx at 36Mbps */ ++ uint32 rx48mbps; /* packets rx at 48Mbps */ ++ uint32 rx54mbps; /* packets rx at 54Mbps */ ++ uint32 rx108mbps; /* packets rx at 108mbps */ ++ uint32 rx162mbps; /* packets rx at 162mbps */ ++ uint32 rx216mbps; /* packets rx at 216 mbps */ ++ uint32 rx270mbps; /* packets rx at 270 mbps */ ++ uint32 rx324mbps; /* packets rx at 324 mbps */ ++ uint32 rx378mbps; /* packets rx at 378 mbps */ ++ uint32 rx432mbps; /* packets rx at 432 mbps */ ++ uint32 rx486mbps; /* packets rx at 486 mbps */ ++ uint32 rx540mbps; /* packets rx at 540 mbps */ ++ ++ /* pkteng rx frame stats */ ++ uint32 pktengrxducast; /* unicast frames rxed by the pkteng code */ ++ uint32 pktengrxdmcast; /* multicast frames rxed by the pkteng code */ ++ ++ uint32 rfdisable; /* count of radio disables */ ++ uint32 bphy_rxcrsglitch; /* PHY count of bphy glitches */ ++ ++ uint32 txexptime; /* Tx frames suppressed due to timer expiration */ ++ ++ uint32 txmpdu_sgi; /* count for sgi transmit */ ++ uint32 rxmpdu_sgi; /* count for sgi received */ ++ uint32 txmpdu_stbc; /* count for stbc transmit */ ++ uint32 rxmpdu_stbc; /* count for stbc received */ ++ ++ uint32 rxundec_mcst; /* dot11WEPUndecryptableCount */ ++ ++ /* WPA2 counters (see rxundec for DecryptFailureCount) */ ++ uint32 tkipmicfaill_mcst; /* TKIPLocalMICFailures */ ++ uint32 tkipcntrmsr_mcst; /* TKIPCounterMeasuresInvoked */ ++ uint32 tkipreplay_mcst; /* TKIPReplays */ ++ uint32 ccmpfmterr_mcst; /* CCMPFormatErrors */ ++ uint32 ccmpreplay_mcst; /* CCMPReplays */ ++ uint32 ccmpundec_mcst; /* CCMPDecryptErrors */ ++ uint32 fourwayfail_mcst; /* FourWayHandshakeFailures */ ++ uint32 wepundec_mcst; /* dot11WEPUndecryptableCount */ ++ uint32 wepicverr_mcst; /* dot11WEPICVErrorCount */ ++ uint32 decsuccess_mcst; /* DecryptSuccessCount */ ++ uint32 tkipicverr_mcst; /* TKIPICVErrorCount */ ++ uint32 wepexcluded_mcst; /* dot11WEPExcludedCount */ ++ ++ uint32 dma_hang; /* count for dma hang */ ++ uint32 reinit; /* count for reinit */ ++ ++ uint32 pstatxucast; /* count of ucast frames xmitted on all psta assoc */ ++ uint32 pstatxnoassoc; /* count of txnoassoc frames xmitted on all psta assoc */ ++ uint32 pstarxucast; /* count of ucast frames received on all psta assoc */ ++ uint32 pstarxbcmc; /* count of bcmc frames received on all psta */ ++ uint32 pstatxbcmc; /* count of bcmc frames transmitted on all psta */ ++ ++ uint32 cso_passthrough; /* hw cso required but passthrough */ ++ uint32 cso_normal; /* hw cso hdr for normal process */ ++ uint32 chained; /* number of frames chained */ ++ uint32 chainedsz1; /* number of chain size 1 frames */ ++ uint32 unchained; /* number of frames not chained */ ++ uint32 maxchainsz; /* max chain size so far */ ++ uint32 currchainsz; /* current chain size */ ++} wl_cnt_t; ++ ++typedef struct { ++ uint16 version; /* see definition of WL_CNT_T_VERSION */ ++ uint16 length; /* length of entire structure */ ++ ++ /* transmit stat counters */ ++ uint32 txframe; /* tx data frames */ ++ uint32 txbyte; /* tx data bytes */ ++ uint32 txretrans; /* tx mac retransmits */ ++ uint32 txerror; /* tx data errors (derived: sum of others) */ ++ uint32 txctl; /* tx management frames */ ++ uint32 txprshort; /* tx short preamble frames */ ++ uint32 txserr; /* tx status errors */ ++ uint32 txnobuf; /* tx out of buffers errors */ ++ uint32 txnoassoc; /* tx discard because we're not associated */ ++ uint32 txrunt; /* tx runt frames */ ++ uint32 txchit; /* tx header cache hit (fastpath) */ ++ uint32 txcmiss; /* tx header cache miss (slowpath) */ ++ ++ /* transmit chip error counters */ ++ uint32 txuflo; /* tx fifo underflows */ ++ uint32 txphyerr; /* tx phy errors (indicated in tx status) */ ++ uint32 txphycrs; ++ ++ /* receive stat counters */ ++ uint32 rxframe; /* rx data frames */ ++ uint32 rxbyte; /* rx data bytes */ ++ uint32 rxerror; /* rx data errors (derived: sum of others) */ ++ uint32 rxctl; /* rx management frames */ ++ uint32 rxnobuf; /* rx out of buffers errors */ ++ uint32 rxnondata; /* rx non data frames in the data channel errors */ ++ uint32 rxbadds; /* rx bad DS errors */ ++ uint32 rxbadcm; /* rx bad control or management frames */ ++ uint32 rxfragerr; /* rx fragmentation errors */ ++ uint32 rxrunt; /* rx runt frames */ ++ uint32 rxgiant; /* rx giant frames */ ++ uint32 rxnoscb; /* rx no scb error */ ++ uint32 rxbadproto; /* rx invalid frames */ ++ uint32 rxbadsrcmac; /* rx frames with Invalid Src Mac */ ++ uint32 rxbadda; /* rx frames tossed for invalid da */ ++ uint32 rxfilter; /* rx frames filtered out */ ++ ++ /* receive chip error counters */ ++ uint32 rxoflo; /* rx fifo overflow errors */ ++ uint32 rxuflo[NFIFO]; /* rx dma descriptor underflow errors */ ++ ++ uint32 d11cnt_txrts_off; /* d11cnt txrts value when reset d11cnt */ ++ uint32 d11cnt_rxcrc_off; /* d11cnt rxcrc value when reset d11cnt */ ++ uint32 d11cnt_txnocts_off; /* d11cnt txnocts value when reset d11cnt */ ++ ++ /* misc counters */ ++ uint32 dmade; /* tx/rx dma descriptor errors */ ++ uint32 dmada; /* tx/rx dma data errors */ ++ uint32 dmape; /* tx/rx dma descriptor protocol errors */ ++ uint32 reset; /* reset count */ ++ uint32 tbtt; /* cnts the TBTT int's */ ++ uint32 txdmawar; ++ uint32 pkt_callback_reg_fail; /* callbacks register failure */ ++ ++ /* MAC counters: 32-bit version of d11.h's macstat_t */ ++ uint32 txallfrm; /* total number of frames sent, incl. Data, ACK, RTS, CTS, ++ * Control Management (includes retransmissions) ++ */ ++ uint32 txrtsfrm; /* number of RTS sent out by the MAC */ ++ uint32 txctsfrm; /* number of CTS sent out by the MAC */ ++ uint32 txackfrm; /* number of ACK frames sent out */ ++ uint32 txdnlfrm; /* Not used */ ++ uint32 txbcnfrm; /* beacons transmitted */ ++ uint32 txfunfl[8]; /* per-fifo tx underflows */ ++ uint32 txtplunfl; /* Template underflows (mac was too slow to transmit ACK/CTS ++ * or BCN) ++ */ ++ uint32 txphyerror; /* Transmit phy error, type of error is reported in tx-status for ++ * driver enqueued frames ++ */ ++ uint32 rxfrmtoolong; /* Received frame longer than legal limit (2346 bytes) */ ++ uint32 rxfrmtooshrt; /* Received frame did not contain enough bytes for its frame type */ ++ uint32 rxinvmachdr; /* Either the protocol version != 0 or frame type not ++ * data/control/management ++ */ ++ uint32 rxbadfcs; /* number of frames for which the CRC check failed in the MAC */ ++ uint32 rxbadplcp; /* parity check of the PLCP header failed */ ++ uint32 rxcrsglitch; /* PHY was able to correlate the preamble but not the header */ ++ uint32 rxstrt; /* Number of received frames with a good PLCP ++ * (i.e. passing parity check) ++ */ ++ uint32 rxdfrmucastmbss; /* Number of received DATA frames with good FCS and matching RA */ ++ uint32 rxmfrmucastmbss; /* number of received mgmt frames with good FCS and matching RA */ ++ uint32 rxcfrmucast; /* number of received CNTRL frames with good FCS and matching RA */ ++ uint32 rxrtsucast; /* number of unicast RTS addressed to the MAC (good FCS) */ ++ uint32 rxctsucast; /* number of unicast CTS addressed to the MAC (good FCS) */ ++ uint32 rxackucast; /* number of ucast ACKS received (good FCS) */ ++ uint32 rxdfrmocast; /* number of received DATA frames (good FCS and not matching RA) */ ++ uint32 rxmfrmocast; /* number of received MGMT frames (good FCS and not matching RA) */ ++ uint32 rxcfrmocast; /* number of received CNTRL frame (good FCS and not matching RA) */ ++ uint32 rxrtsocast; /* number of received RTS not addressed to the MAC */ ++ uint32 rxctsocast; /* number of received CTS not addressed to the MAC */ ++ uint32 rxdfrmmcast; /* number of RX Data multicast frames received by the MAC */ ++ uint32 rxmfrmmcast; /* number of RX Management multicast frames received by the MAC */ ++ uint32 rxcfrmmcast; /* number of RX Control multicast frames received by the MAC ++ * (unlikely to see these) ++ */ ++ uint32 rxbeaconmbss; /* beacons received from member of BSS */ ++ uint32 rxdfrmucastobss; /* number of unicast frames addressed to the MAC from ++ * other BSS (WDS FRAME) ++ */ ++ uint32 rxbeaconobss; /* beacons received from other BSS */ ++ uint32 rxrsptmout; /* Number of response timeouts for transmitted frames ++ * expecting a response ++ */ ++ uint32 bcntxcancl; /* transmit beacons canceled due to receipt of beacon (IBSS) */ ++ uint32 rxf0ovfl; /* Number of receive fifo 0 overflows */ ++ uint32 rxf1ovfl; /* Number of receive fifo 1 overflows (obsolete) */ ++ uint32 rxf2ovfl; /* Number of receive fifo 2 overflows (obsolete) */ ++ uint32 txsfovfl; /* Number of transmit status fifo overflows (obsolete) */ ++ uint32 pmqovfl; /* Number of PMQ overflows */ ++ uint32 rxcgprqfrm; /* Number of received Probe requests that made it into ++ * the PRQ fifo ++ */ ++ uint32 rxcgprsqovfl; /* Rx Probe Request Que overflow in the AP */ ++ uint32 txcgprsfail; /* Tx Probe Response Fail. AP sent probe response but did ++ * not get ACK ++ */ ++ uint32 txcgprssuc; /* Tx Probe Response Success (ACK was received) */ ++ uint32 prs_timeout; /* Number of probe requests that were dropped from the PRQ ++ * fifo because a probe response could not be sent out within ++ * the time limit defined in M_PRS_MAXTIME ++ */ ++ uint32 rxnack; ++ uint32 frmscons; ++ uint32 txnack; ++ uint32 txglitch_nack; /* obsolete */ ++ uint32 txburst; /* obsolete */ ++ ++ /* 802.11 MIB counters, pp. 614 of 802.11 reaff doc. */ ++ uint32 txfrag; /* dot11TransmittedFragmentCount */ ++ uint32 txmulti; /* dot11MulticastTransmittedFrameCount */ ++ uint32 txfail; /* dot11FailedCount */ ++ uint32 txretry; /* dot11RetryCount */ ++ uint32 txretrie; /* dot11MultipleRetryCount */ ++ uint32 rxdup; /* dot11FrameduplicateCount */ ++ uint32 txrts; /* dot11RTSSuccessCount */ ++ uint32 txnocts; /* dot11RTSFailureCount */ ++ uint32 txnoack; /* dot11ACKFailureCount */ ++ uint32 rxfrag; /* dot11ReceivedFragmentCount */ ++ uint32 rxmulti; /* dot11MulticastReceivedFrameCount */ ++ uint32 rxcrc; /* dot11FCSErrorCount */ ++ uint32 txfrmsnt; /* dot11TransmittedFrameCount (bogus MIB?) */ ++ uint32 rxundec; /* dot11WEPUndecryptableCount */ ++ ++ /* WPA2 counters (see rxundec for DecryptFailureCount) */ ++ uint32 tkipmicfaill; /* TKIPLocalMICFailures */ ++ uint32 tkipcntrmsr; /* TKIPCounterMeasuresInvoked */ ++ uint32 tkipreplay; /* TKIPReplays */ ++ uint32 ccmpfmterr; /* CCMPFormatErrors */ ++ uint32 ccmpreplay; /* CCMPReplays */ ++ uint32 ccmpundec; /* CCMPDecryptErrors */ ++ uint32 fourwayfail; /* FourWayHandshakeFailures */ ++ uint32 wepundec; /* dot11WEPUndecryptableCount */ ++ uint32 wepicverr; /* dot11WEPICVErrorCount */ ++ uint32 decsuccess; /* DecryptSuccessCount */ ++ uint32 tkipicverr; /* TKIPICVErrorCount */ ++ uint32 wepexcluded; /* dot11WEPExcludedCount */ ++ ++ uint32 rxundec_mcst; /* dot11WEPUndecryptableCount */ ++ ++ /* WPA2 counters (see rxundec for DecryptFailureCount) */ ++ uint32 tkipmicfaill_mcst; /* TKIPLocalMICFailures */ ++ uint32 tkipcntrmsr_mcst; /* TKIPCounterMeasuresInvoked */ ++ uint32 tkipreplay_mcst; /* TKIPReplays */ ++ uint32 ccmpfmterr_mcst; /* CCMPFormatErrors */ ++ uint32 ccmpreplay_mcst; /* CCMPReplays */ ++ uint32 ccmpundec_mcst; /* CCMPDecryptErrors */ ++ uint32 fourwayfail_mcst; /* FourWayHandshakeFailures */ ++ uint32 wepundec_mcst; /* dot11WEPUndecryptableCount */ ++ uint32 wepicverr_mcst; /* dot11WEPICVErrorCount */ ++ uint32 decsuccess_mcst; /* DecryptSuccessCount */ ++ uint32 tkipicverr_mcst; /* TKIPICVErrorCount */ ++ uint32 wepexcluded_mcst; /* dot11WEPExcludedCount */ ++ ++ uint32 txchanrej; /* Tx frames suppressed due to channel rejection */ ++ uint32 txexptime; /* Tx frames suppressed due to timer expiration */ ++ uint32 psmwds; /* Count PSM watchdogs */ ++ uint32 phywatchdog; /* Count Phy watchdogs (triggered by ucode) */ ++ ++ /* MBSS counters, AP only */ ++ uint32 prq_entries_handled; /* PRQ entries read in */ ++ uint32 prq_undirected_entries; /* which were bcast bss & ssid */ ++ uint32 prq_bad_entries; /* which could not be translated to info */ ++ uint32 atim_suppress_count; /* TX suppressions on ATIM fifo */ ++ uint32 bcn_template_not_ready; /* Template marked in use on send bcn ... */ ++ uint32 bcn_template_not_ready_done; /* ...but "DMA done" interrupt rcvd */ ++ uint32 late_tbtt_dpc; /* TBTT DPC did not happen in time */ ++ ++ /* per-rate receive stat counters */ ++ uint32 rx1mbps; /* packets rx at 1Mbps */ ++ uint32 rx2mbps; /* packets rx at 2Mbps */ ++ uint32 rx5mbps5; /* packets rx at 5.5Mbps */ ++ uint32 rx6mbps; /* packets rx at 6Mbps */ ++ uint32 rx9mbps; /* packets rx at 9Mbps */ ++ uint32 rx11mbps; /* packets rx at 11Mbps */ ++ uint32 rx12mbps; /* packets rx at 12Mbps */ ++ uint32 rx18mbps; /* packets rx at 18Mbps */ ++ uint32 rx24mbps; /* packets rx at 24Mbps */ ++ uint32 rx36mbps; /* packets rx at 36Mbps */ ++ uint32 rx48mbps; /* packets rx at 48Mbps */ ++ uint32 rx54mbps; /* packets rx at 54Mbps */ ++ uint32 rx108mbps; /* packets rx at 108mbps */ ++ uint32 rx162mbps; /* packets rx at 162mbps */ ++ uint32 rx216mbps; /* packets rx at 216 mbps */ ++ uint32 rx270mbps; /* packets rx at 270 mbps */ ++ uint32 rx324mbps; /* packets rx at 324 mbps */ ++ uint32 rx378mbps; /* packets rx at 378 mbps */ ++ uint32 rx432mbps; /* packets rx at 432 mbps */ ++ uint32 rx486mbps; /* packets rx at 486 mbps */ ++ uint32 rx540mbps; /* packets rx at 540 mbps */ ++ ++ /* pkteng rx frame stats */ ++ uint32 pktengrxducast; /* unicast frames rxed by the pkteng code */ ++ uint32 pktengrxdmcast; /* multicast frames rxed by the pkteng code */ ++ ++ uint32 rfdisable; /* count of radio disables */ ++ uint32 bphy_rxcrsglitch; /* PHY count of bphy glitches */ ++ ++ uint32 txmpdu_sgi; /* count for sgi transmit */ ++ uint32 rxmpdu_sgi; /* count for sgi received */ ++ uint32 txmpdu_stbc; /* count for stbc transmit */ ++ uint32 rxmpdu_stbc; /* count for stbc received */ ++} wl_cnt_ver_six_t; ++ ++ ++#ifndef LINUX_POSTMOGRIFY_REMOVAL ++#define WL_DELTA_STATS_T_VERSION 1 /* current version of wl_delta_stats_t struct */ ++ ++typedef struct { ++ uint16 version; /* see definition of WL_DELTA_STATS_T_VERSION */ ++ uint16 length; /* length of entire structure */ ++ ++ /* transmit stat counters */ ++ uint32 txframe; /* tx data frames */ ++ uint32 txbyte; /* tx data bytes */ ++ uint32 txretrans; /* tx mac retransmits */ ++ uint32 txfail; /* tx failures */ ++ ++ /* receive stat counters */ ++ uint32 rxframe; /* rx data frames */ ++ uint32 rxbyte; /* rx data bytes */ ++ ++ /* per-rate receive stat counters */ ++ uint32 rx1mbps; /* packets rx at 1Mbps */ ++ uint32 rx2mbps; /* packets rx at 2Mbps */ ++ uint32 rx5mbps5; /* packets rx at 5.5Mbps */ ++ uint32 rx6mbps; /* packets rx at 6Mbps */ ++ uint32 rx9mbps; /* packets rx at 9Mbps */ ++ uint32 rx11mbps; /* packets rx at 11Mbps */ ++ uint32 rx12mbps; /* packets rx at 12Mbps */ ++ uint32 rx18mbps; /* packets rx at 18Mbps */ ++ uint32 rx24mbps; /* packets rx at 24Mbps */ ++ uint32 rx36mbps; /* packets rx at 36Mbps */ ++ uint32 rx48mbps; /* packets rx at 48Mbps */ ++ uint32 rx54mbps; /* packets rx at 54Mbps */ ++ uint32 rx108mbps; /* packets rx at 108mbps */ ++ uint32 rx162mbps; /* packets rx at 162mbps */ ++ uint32 rx216mbps; /* packets rx at 216 mbps */ ++ uint32 rx270mbps; /* packets rx at 270 mbps */ ++ uint32 rx324mbps; /* packets rx at 324 mbps */ ++ uint32 rx378mbps; /* packets rx at 378 mbps */ ++ uint32 rx432mbps; /* packets rx at 432 mbps */ ++ uint32 rx486mbps; /* packets rx at 486 mbps */ ++ uint32 rx540mbps; /* packets rx at 540 mbps */ ++} wl_delta_stats_t; ++#endif /* LINUX_POSTMOGRIFY_REMOVAL */ ++ ++#define WL_WME_CNT_VERSION 1 /* current version of wl_wme_cnt_t */ ++ ++typedef struct { ++ uint32 packets; ++ uint32 bytes; ++} wl_traffic_stats_t; ++ ++typedef struct { ++ uint16 version; /* see definition of WL_WME_CNT_VERSION */ ++ uint16 length; /* length of entire structure */ ++ ++ wl_traffic_stats_t tx[AC_COUNT]; /* Packets transmitted */ ++ wl_traffic_stats_t tx_failed[AC_COUNT]; /* Packets dropped or failed to transmit */ ++ wl_traffic_stats_t rx[AC_COUNT]; /* Packets received */ ++ wl_traffic_stats_t rx_failed[AC_COUNT]; /* Packets failed to receive */ ++ ++ wl_traffic_stats_t forward[AC_COUNT]; /* Packets forwarded by AP */ ++ ++ wl_traffic_stats_t tx_expired[AC_COUNT]; /* packets dropped due to lifetime expiry */ ++ ++} wl_wme_cnt_t; ++ ++struct wl_msglevel2 { ++ uint32 low; ++ uint32 high; ++}; ++ ++typedef struct wl_mkeep_alive_pkt { ++ uint16 version; /* Version for mkeep_alive */ ++ uint16 length; /* length of fixed parameters in the structure */ ++ uint32 period_msec; ++ uint16 len_bytes; ++ uint8 keep_alive_id; /* 0 - 3 for N = 4 */ ++ uint8 data[1]; ++} wl_mkeep_alive_pkt_t; ++ ++#define WL_MKEEP_ALIVE_VERSION 1 ++#define WL_MKEEP_ALIVE_FIXED_LEN OFFSETOF(wl_mkeep_alive_pkt_t, data) ++#define WL_MKEEP_ALIVE_PRECISION 500 ++ ++#ifndef LINUX_POSTMOGRIFY_REMOVAL ++#ifdef WLBA ++ ++#define WLC_BA_CNT_VERSION 1 /* current version of wlc_ba_cnt_t */ ++ ++/* block ack related stats */ ++typedef struct wlc_ba_cnt { ++ uint16 version; /* WLC_BA_CNT_VERSION */ ++ uint16 length; /* length of entire structure */ ++ ++ /* transmit stat counters */ ++ uint32 txpdu; /* pdus sent */ ++ uint32 txsdu; /* sdus sent */ ++ uint32 txfc; /* tx side flow controlled packets */ ++ uint32 txfci; /* tx side flow control initiated */ ++ uint32 txretrans; /* retransmitted pdus */ ++ uint32 txbatimer; /* ba resend due to timer */ ++ uint32 txdrop; /* dropped packets */ ++ uint32 txaddbareq; /* addba req sent */ ++ uint32 txaddbaresp; /* addba resp sent */ ++ uint32 txdelba; /* delba sent */ ++ uint32 txba; /* ba sent */ ++ uint32 txbar; /* bar sent */ ++ uint32 txpad[4]; /* future */ ++ ++ /* receive side counters */ ++ uint32 rxpdu; /* pdus recd */ ++ uint32 rxqed; /* pdus buffered before sending up */ ++ uint32 rxdup; /* duplicate pdus */ ++ uint32 rxnobuf; /* pdus discarded due to no buf */ ++ uint32 rxaddbareq; /* addba req recd */ ++ uint32 rxaddbaresp; /* addba resp recd */ ++ uint32 rxdelba; /* delba recd */ ++ uint32 rxba; /* ba recd */ ++ uint32 rxbar; /* bar recd */ ++ uint32 rxinvba; /* invalid ba recd */ ++ uint32 rxbaholes; /* ba recd with holes */ ++ uint32 rxunexp; /* unexpected packets */ ++ uint32 rxpad[4]; /* future */ ++} wlc_ba_cnt_t; ++#endif /* WLBA */ ++ ++/* structure for per-tid ampdu control */ ++struct ampdu_tid_control { ++ uint8 tid; /* tid */ ++ uint8 enable; /* enable/disable */ ++}; ++ ++/* structure for identifying ea/tid for sending addba/delba */ ++struct ampdu_ea_tid { ++ struct ether_addr ea; /* Station address */ ++ uint8 tid; /* tid */ ++}; ++/* structure for identifying retry/tid for retry_limit_tid/rr_retry_limit_tid */ ++struct ampdu_retry_tid { ++ uint8 tid; /* tid */ ++ uint8 retry; /* retry value */ ++}; ++ ++/* Different discovery modes for dpt */ ++#define DPT_DISCOVERY_MANUAL 0x01 /* manual discovery mode */ ++#define DPT_DISCOVERY_AUTO 0x02 /* auto discovery mode */ ++#define DPT_DISCOVERY_SCAN 0x04 /* scan-based discovery mode */ ++ ++/* different path selection values */ ++#define DPT_PATHSEL_AUTO 0 /* auto mode for path selection */ ++#define DPT_PATHSEL_DIRECT 1 /* always use direct DPT path */ ++#define DPT_PATHSEL_APPATH 2 /* always use AP path */ ++ ++/* different ops for deny list */ ++#define DPT_DENY_LIST_ADD 1 /* add to dpt deny list */ ++#define DPT_DENY_LIST_REMOVE 2 /* remove from dpt deny list */ ++ ++/* different ops for manual end point */ ++#define DPT_MANUAL_EP_CREATE 1 /* create manual dpt endpoint */ ++#define DPT_MANUAL_EP_MODIFY 2 /* modify manual dpt endpoint */ ++#define DPT_MANUAL_EP_DELETE 3 /* delete manual dpt endpoint */ ++ ++/* structure for dpt iovars */ ++typedef struct dpt_iovar { ++ struct ether_addr ea; /* Station address */ ++ uint8 mode; /* mode: depends on iovar */ ++ uint32 pad; /* future */ ++} dpt_iovar_t; ++ ++/* flags to indicate DPT status */ ++#define DPT_STATUS_ACTIVE 0x01 /* link active (though may be suspended) */ ++#define DPT_STATUS_AES 0x02 /* link secured through AES encryption */ ++#define DPT_STATUS_FAILED 0x04 /* DPT link failed */ ++ ++#define DPT_FNAME_LEN 48 /* Max length of friendly name */ ++ ++typedef struct dpt_status { ++ uint8 status; /* flags to indicate status */ ++ uint8 fnlen; /* length of friendly name */ ++ uchar name[DPT_FNAME_LEN]; /* friendly name */ ++ uint32 rssi; /* RSSI of the link */ ++ sta_info_t sta; /* sta info */ ++} dpt_status_t; ++ ++/* structure for dpt list */ ++typedef struct dpt_list { ++ uint32 num; /* number of entries in struct */ ++ dpt_status_t status[1]; /* per station info */ ++} dpt_list_t; ++ ++/* structure for dpt friendly name */ ++typedef struct dpt_fname { ++ uint8 len; /* length of friendly name */ ++ uchar name[DPT_FNAME_LEN]; /* friendly name */ ++} dpt_fname_t; ++ ++#define BDD_FNAME_LEN 32 /* Max length of friendly name */ ++typedef struct bdd_fname { ++ uint8 len; /* length of friendly name */ ++ uchar name[BDD_FNAME_LEN]; /* friendly name */ ++} bdd_fname_t; ++ ++/* structure for addts arguments */ ++/* For ioctls that take a list of TSPEC */ ++struct tslist { ++ int count; /* number of tspecs */ ++ struct tsinfo_arg tsinfo[1]; /* variable length array of tsinfo */ ++}; ++ ++#ifdef WLTDLS ++/* different ops for manual end point */ ++#define TDLS_MANUAL_EP_CREATE 1 /* create manual dpt endpoint */ ++#define TDLS_MANUAL_EP_MODIFY 2 /* modify manual dpt endpoint */ ++#define TDLS_MANUAL_EP_DELETE 3 /* delete manual dpt endpoint */ ++#define TDLS_MANUAL_EP_PM 4 /* put dpt endpoint in PM mode */ ++#define TDLS_MANUAL_EP_WAKE 5 /* wake up dpt endpoint from PM */ ++#define TDLS_MANUAL_EP_DISCOVERY 6 /* discover if endpoint is TDLS capable */ ++#define TDLS_MANUAL_EP_CHSW 7 /* channel switch */ ++ ++/* structure for tdls iovars */ ++typedef struct tdls_iovar { ++ struct ether_addr ea; /* Station address */ ++ uint8 mode; /* mode: depends on iovar */ ++ chanspec_t chanspec; ++ uint32 pad; /* future */ ++} tdls_iovar_t; ++#endif /* WLTDLS */ ++ ++/* structure for addts/delts arguments */ ++typedef struct tspec_arg { ++ uint16 version; /* see definition of TSPEC_ARG_VERSION */ ++ uint16 length; /* length of entire structure */ ++ uint flag; /* bit field */ ++ /* TSPEC Arguments */ ++ struct tsinfo_arg tsinfo; /* TS Info bit field */ ++ uint16 nom_msdu_size; /* (Nominal or fixed) MSDU Size (bytes) */ ++ uint16 max_msdu_size; /* Maximum MSDU Size (bytes) */ ++ uint min_srv_interval; /* Minimum Service Interval (us) */ ++ uint max_srv_interval; /* Maximum Service Interval (us) */ ++ uint inactivity_interval; /* Inactivity Interval (us) */ ++ uint suspension_interval; /* Suspension Interval (us) */ ++ uint srv_start_time; /* Service Start Time (us) */ ++ uint min_data_rate; /* Minimum Data Rate (bps) */ ++ uint mean_data_rate; /* Mean Data Rate (bps) */ ++ uint peak_data_rate; /* Peak Data Rate (bps) */ ++ uint max_burst_size; /* Maximum Burst Size (bytes) */ ++ uint delay_bound; /* Delay Bound (us) */ ++ uint min_phy_rate; /* Minimum PHY Rate (bps) */ ++ uint16 surplus_bw; /* Surplus Bandwidth Allowance (range 1.0 to 8.0) */ ++ uint16 medium_time; /* Medium Time (32 us/s periods) */ ++ uint8 dialog_token; /* dialog token */ ++} tspec_arg_t; ++ ++/* tspec arg for desired station */ ++typedef struct tspec_per_sta_arg { ++ struct ether_addr ea; ++ struct tspec_arg ts; ++} tspec_per_sta_arg_t; ++ ++/* structure for max bandwidth for each access category */ ++typedef struct wme_max_bandwidth { ++ uint32 ac[AC_COUNT]; /* max bandwidth for each access category */ ++} wme_max_bandwidth_t; ++ ++#define WL_WME_MBW_PARAMS_IO_BYTES (sizeof(wme_max_bandwidth_t)) ++ ++/* current version of wl_tspec_arg_t struct */ ++#define TSPEC_ARG_VERSION 2 /* current version of wl_tspec_arg_t struct */ ++#define TSPEC_ARG_LENGTH 55 /* argument length from tsinfo to medium_time */ ++#define TSPEC_DEFAULT_DIALOG_TOKEN 42 /* default dialog token */ ++#define TSPEC_DEFAULT_SBW_FACTOR 0x3000 /* default surplus bw */ ++ ++ ++#define WL_WOWL_KEEPALIVE_MAX_PACKET_SIZE 80 ++#define WLC_WOWL_MAX_KEEPALIVE 2 ++ ++/* define for flag */ ++#define TSPEC_PENDING 0 /* TSPEC pending */ ++#define TSPEC_ACCEPTED 1 /* TSPEC accepted */ ++#define TSPEC_REJECTED 2 /* TSPEC rejected */ ++#define TSPEC_UNKNOWN 3 /* TSPEC unknown */ ++#define TSPEC_STATUS_MASK 7 /* TSPEC status mask */ ++ ++ ++/* Software feature flag defines used by wlfeatureflag */ ++#ifdef WLAFTERBURNER ++#define WL_SWFL_ABBFL 0x0001 /* Allow Afterburner on systems w/o hardware BFL */ ++#define WL_SWFL_ABENCORE 0x0002 /* Allow AB on non-4318E chips */ ++#endif /* WLAFTERBURNER */ ++#define WL_SWFL_NOHWRADIO 0x0004 ++#define WL_SWFL_FLOWCONTROL 0x0008 /* Enable backpressure to OS stack */ ++#define WL_SWFL_WLBSSSORT 0x0010 /* Per-port supports sorting of BSS */ ++ ++#define WL_LIFETIME_MAX 0xFFFF /* Max value in ms */ ++ ++/* Packet lifetime configuration per ac */ ++typedef struct wl_lifetime { ++ uint32 ac; /* access class */ ++ uint32 lifetime; /* Packet lifetime value in ms */ ++} wl_lifetime_t; ++ ++/* Channel Switch Announcement param */ ++typedef struct wl_chan_switch { ++ uint8 mode; /* value 0 or 1 */ ++ uint8 count; /* count # of beacons before switching */ ++ chanspec_t chspec; /* chanspec */ ++ uint8 reg; /* regulatory class */ ++} wl_chan_switch_t; ++#endif /* LINUX_POSTMOGRIFY_REMOVAL */ ++ ++/* Roaming trigger definitions for WLC_SET_ROAM_TRIGGER. ++ * ++ * (-100 < value < 0) value is used directly as a roaming trigger in dBm ++ * (0 <= value) value specifies a logical roaming trigger level from ++ * the list below ++ * ++ * WLC_GET_ROAM_TRIGGER always returns roaming trigger value in dBm, never ++ * the logical roam trigger value. ++ */ ++#define WLC_ROAM_TRIGGER_DEFAULT 0 /* default roaming trigger */ ++#define WLC_ROAM_TRIGGER_BANDWIDTH 1 /* optimize for bandwidth roaming trigger */ ++#define WLC_ROAM_TRIGGER_DISTANCE 2 /* optimize for distance roaming trigger */ ++#define WLC_ROAM_TRIGGER_AUTO 3 /* auto-detect environment */ ++#define WLC_ROAM_TRIGGER_MAX_VALUE 3 /* max. valid value */ ++ ++#define WLC_ROAM_NEVER_ROAM_TRIGGER (-100) /* Avoid Roaming by setting a large value */ ++ ++/* Preferred Network Offload (PNO, formerly PFN) defines */ ++#define WPA_AUTH_PFN_ANY 0xffffffff /* for PFN, match only ssid */ ++ ++enum { ++ PFN_LIST_ORDER, ++ PFN_RSSI ++}; ++ ++enum { ++ DISABLE, ++ ENABLE ++}; ++ ++enum { ++ OFF_ADAPT, ++ SMART_ADAPT, ++ STRICT_ADAPT, ++ SLOW_ADAPT ++}; ++ ++#define SORT_CRITERIA_BIT 0 ++#define AUTO_NET_SWITCH_BIT 1 ++#define ENABLE_BKGRD_SCAN_BIT 2 ++#define IMMEDIATE_SCAN_BIT 3 ++#define AUTO_CONNECT_BIT 4 ++#define ENABLE_BD_SCAN_BIT 5 ++#define ENABLE_ADAPTSCAN_BIT 6 ++#define IMMEDIATE_EVENT_BIT 8 ++ ++#define SORT_CRITERIA_MASK 0x0001 ++#define AUTO_NET_SWITCH_MASK 0x0002 ++#define ENABLE_BKGRD_SCAN_MASK 0x0004 ++#define IMMEDIATE_SCAN_MASK 0x0008 ++#define AUTO_CONNECT_MASK 0x0010 ++ ++#define ENABLE_BD_SCAN_MASK 0x0020 ++#define ENABLE_ADAPTSCAN_MASK 0x00c0 ++#define IMMEDIATE_EVENT_MASK 0x0100 ++ ++#define PFN_VERSION 2 ++#define PFN_SCANRESULT_VERSION 1 ++#define MAX_PFN_LIST_COUNT 16 ++ ++#define PFN_COMPLETE 1 ++#define PFN_INCOMPLETE 0 ++ ++#define DEFAULT_BESTN 2 ++#define DEFAULT_MSCAN 0 ++#define DEFAULT_REPEAT 10 ++#define DEFAULT_EXP 2 ++ ++/* PFN network info structure */ ++typedef struct wl_pfn_subnet_info { ++ struct ether_addr BSSID; ++ uint8 channel; /* channel number only */ ++ uint8 SSID_len; ++ uint8 SSID[32]; ++} wl_pfn_subnet_info_t; ++ ++typedef struct wl_pfn_net_info { ++ wl_pfn_subnet_info_t pfnsubnet; ++ int16 RSSI; /* receive signal strength (in dBm) */ ++ uint16 timestamp; /* age in seconds */ ++} wl_pfn_net_info_t; ++ ++typedef struct wl_pfn_scanresults { ++ uint32 version; ++ uint32 status; ++ uint32 count; ++ wl_pfn_net_info_t netinfo[1]; ++} wl_pfn_scanresults_t; ++ ++/* PFN data structure */ ++typedef struct wl_pfn_param { ++ int32 version; /* PNO parameters version */ ++ int32 scan_freq; /* Scan frequency */ ++ int32 lost_network_timeout; /* Timeout in sec. to declare ++ * discovered network as lost ++ */ ++ int16 flags; /* Bit field to control features ++ * of PFN such as sort criteria auto ++ * enable switch and background scan ++ */ ++ int16 rssi_margin; /* Margin to avoid jitter for choosing a ++ * PFN based on RSSI sort criteria ++ */ ++ uint8 bestn; /* number of best networks in each scan */ ++ uint8 mscan; /* number of scans recorded */ ++ uint8 repeat; /* Minimum number of scan intervals ++ *before scan frequency changes in adaptive scan ++ */ ++ uint8 exp; /* Exponent of 2 for maximum scan interval */ ++#if !defined(WLC_PATCH) || !defined(BCM43362A2) ++ int32 slow_freq; /* slow scan period */ ++#endif /* !WLC_PATCH || !BCM43362A2 */ ++} wl_pfn_param_t; ++ ++typedef struct wl_pfn { ++ wlc_ssid_t ssid; /* ssid name and its length */ ++ int32 bss_type; /* IBSS or infrastructure */ ++ int32 infra; /* BSS Vs IBSS */ ++ int32 auth; /* Open Vs Closed */ ++ int32 wpa_auth; /* WPA type */ ++ int32 wsec; /* wsec value */ ++} wl_pfn_t; ++#define WL_PFN_HIDDEN_BIT 2 ++#define PNO_SCAN_MAX_FW 508*1000 /* max time scan time in msec */ ++#define PNO_SCAN_MAX_FW_SEC PNO_SCAN_MAX_FW/1000 /* max time scan time in SEC */ ++#define PNO_SCAN_MIN_FW_SEC 10 /* min time scan time in SEC */ ++#define WL_PFN_HIDDEN_MASK 0x4 ++ ++/* TCP Checksum Offload defines */ ++#define TOE_TX_CSUM_OL 0x00000001 ++#define TOE_RX_CSUM_OL 0x00000002 ++ ++/* TCP Checksum Offload error injection for testing */ ++#define TOE_ERRTEST_TX_CSUM 0x00000001 ++#define TOE_ERRTEST_RX_CSUM 0x00000002 ++#define TOE_ERRTEST_RX_CSUM2 0x00000004 ++ ++struct toe_ol_stats_t { ++ /* Num of tx packets that don't need to be checksummed */ ++ uint32 tx_summed; ++ ++ /* Num of tx packets where checksum is filled by offload engine */ ++ uint32 tx_iph_fill; ++ uint32 tx_tcp_fill; ++ uint32 tx_udp_fill; ++ uint32 tx_icmp_fill; ++ ++ /* Num of rx packets where toe finds out if checksum is good or bad */ ++ uint32 rx_iph_good; ++ uint32 rx_iph_bad; ++ uint32 rx_tcp_good; ++ uint32 rx_tcp_bad; ++ uint32 rx_udp_good; ++ uint32 rx_udp_bad; ++ uint32 rx_icmp_good; ++ uint32 rx_icmp_bad; ++ ++ /* Num of tx packets in which csum error is injected */ ++ uint32 tx_tcp_errinj; ++ uint32 tx_udp_errinj; ++ uint32 tx_icmp_errinj; ++ ++ /* Num of rx packets in which csum error is injected */ ++ uint32 rx_tcp_errinj; ++ uint32 rx_udp_errinj; ++ uint32 rx_icmp_errinj; ++}; ++ ++/* ARP Offload feature flags for arp_ol iovar */ ++#define ARP_OL_AGENT 0x00000001 ++#define ARP_OL_SNOOP 0x00000002 ++#define ARP_OL_HOST_AUTO_REPLY 0x00000004 ++#define ARP_OL_PEER_AUTO_REPLY 0x00000008 ++ ++/* ARP Offload error injection */ ++#define ARP_ERRTEST_REPLY_PEER 0x1 ++#define ARP_ERRTEST_REPLY_HOST 0x2 ++ ++#define ARP_MULTIHOMING_MAX 8 /* Maximum local host IP addresses */ ++#define ND_MULTIHOMING_MAX 8 /* Maximum local host IP addresses */ ++ ++/* Arp offload statistic counts */ ++struct arp_ol_stats_t { ++ uint32 host_ip_entries; /* Host IP table addresses (more than one if multihomed) */ ++ uint32 host_ip_overflow; /* Host IP table additions skipped due to overflow */ ++ ++ uint32 arp_table_entries; /* ARP table entries */ ++ uint32 arp_table_overflow; /* ARP table additions skipped due to overflow */ ++ ++ uint32 host_request; /* ARP requests from host */ ++ uint32 host_reply; /* ARP replies from host */ ++ uint32 host_service; /* ARP requests from host serviced by ARP Agent */ ++ ++ uint32 peer_request; /* ARP requests received from network */ ++ uint32 peer_request_drop; /* ARP requests from network that were dropped */ ++ uint32 peer_reply; /* ARP replies received from network */ ++ uint32 peer_reply_drop; /* ARP replies from network that were dropped */ ++ uint32 peer_service; /* ARP request from host serviced by ARP Agent */ ++}; ++ ++/* NS offload statistic counts */ ++struct nd_ol_stats_t { ++ uint32 host_ip_entries; /* Host IP table addresses (more than one if multihomed) */ ++ uint32 host_ip_overflow; /* Host IP table additions skipped due to overflow */ ++ uint32 peer_request; /* NS requests received from network */ ++ uint32 peer_request_drop; /* NS requests from network that were dropped */ ++ uint32 peer_reply_drop; /* NA replies from network that were dropped */ ++ uint32 peer_service; /* NS request from host serviced by firmware */ ++}; ++ ++/* ++ * Keep-alive packet offloading. ++ */ ++ ++/* NAT keep-alive packets format: specifies the re-transmission period, the packet ++ * length, and packet contents. ++ */ ++typedef struct wl_keep_alive_pkt { ++ uint32 period_msec; /* Retransmission period (0 to disable packet re-transmits) */ ++ uint16 len_bytes; /* Size of packet to transmit (0 to disable packet re-transmits) */ ++ uint8 data[1]; /* Variable length packet to transmit. Contents should include ++ * entire ethernet packet (enet header, IP header, UDP header, ++ * and UDP payload) in network byte order. ++ */ ++} wl_keep_alive_pkt_t; ++ ++#define WL_KEEP_ALIVE_FIXED_LEN OFFSETOF(wl_keep_alive_pkt_t, data) ++ ++/* ++ * Dongle pattern matching filter. ++ */ ++ ++/* Packet filter types. Currently, only pattern matching is supported. */ ++typedef enum wl_pkt_filter_type { ++ WL_PKT_FILTER_TYPE_PATTERN_MATCH /* Pattern matching filter */ ++} wl_pkt_filter_type_t; ++ ++#define WL_PKT_FILTER_TYPE wl_pkt_filter_type_t ++ ++/* Pattern matching filter. Specifies an offset within received packets to ++ * start matching, the pattern to match, the size of the pattern, and a bitmask ++ * that indicates which bits within the pattern should be matched. ++ */ ++typedef struct wl_pkt_filter_pattern { ++ uint32 offset; /* Offset within received packet to start pattern matching. ++ * Offset '0' is the first byte of the ethernet header. ++ */ ++ uint32 size_bytes; /* Size of the pattern. Bitmask must be the same size. */ ++ uint8 mask_and_pattern[1]; /* Variable length mask and pattern data. mask starts ++ * at offset 0. Pattern immediately follows mask. ++ */ ++} wl_pkt_filter_pattern_t; ++ ++/* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */ ++typedef struct wl_pkt_filter { ++ uint32 id; /* Unique filter id, specified by app. */ ++ uint32 type; /* Filter type (WL_PKT_FILTER_TYPE_xxx). */ ++ uint32 negate_match; /* Negate the result of filter matches */ ++ union { /* Filter definitions */ ++ wl_pkt_filter_pattern_t pattern; /* Pattern matching filter */ ++ } u; ++} wl_pkt_filter_t; ++ ++#define WL_PKT_FILTER_FIXED_LEN OFFSETOF(wl_pkt_filter_t, u) ++#define WL_PKT_FILTER_PATTERN_FIXED_LEN OFFSETOF(wl_pkt_filter_pattern_t, mask_and_pattern) ++ ++/* IOVAR "pkt_filter_enable" parameter. */ ++typedef struct wl_pkt_filter_enable { ++ uint32 id; /* Unique filter id */ ++ uint32 enable; /* Enable/disable bool */ ++} wl_pkt_filter_enable_t; ++ ++/* IOVAR "pkt_filter_list" parameter. Used to retrieve a list of installed filters. */ ++typedef struct wl_pkt_filter_list { ++ uint32 num; /* Number of installed packet filters */ ++ wl_pkt_filter_t filter[1]; /* Variable array of packet filters. */ ++} wl_pkt_filter_list_t; ++ ++#define WL_PKT_FILTER_LIST_FIXED_LEN OFFSETOF(wl_pkt_filter_list_t, filter) ++ ++/* IOVAR "pkt_filter_stats" parameter. Used to retrieve debug statistics. */ ++typedef struct wl_pkt_filter_stats { ++ uint32 num_pkts_matched; /* # filter matches for specified filter id */ ++ uint32 num_pkts_forwarded; /* # packets fwded from dongle to host for all filters */ ++ uint32 num_pkts_discarded; /* # packets discarded by dongle for all filters */ ++} wl_pkt_filter_stats_t; ++ ++/* Sequential Commands ioctl */ ++typedef struct wl_seq_cmd_ioctl { ++ uint32 cmd; /* common ioctl definition */ ++ uint32 len; /* length of user buffer */ ++} wl_seq_cmd_ioctl_t; ++ ++#define WL_SEQ_CMD_ALIGN_BYTES 4 ++ ++/* These are the set of get IOCTLs that should be allowed when using ++ * IOCTL sequence commands. These are issued implicitly by wl.exe each time ++ * it is invoked. We never want to buffer these, or else wl.exe will stop working. ++ */ ++#define WL_SEQ_CMDS_GET_IOCTL_FILTER(cmd) \ ++ (((cmd) == WLC_GET_MAGIC) || \ ++ ((cmd) == WLC_GET_VERSION) || \ ++ ((cmd) == WLC_GET_AP) || \ ++ ((cmd) == WLC_GET_INSTANCE)) ++ ++/* ++ * Packet engine interface ++ */ ++ ++#define WL_PKTENG_PER_TX_START 0x01 ++#define WL_PKTENG_PER_TX_STOP 0x02 ++#define WL_PKTENG_PER_RX_START 0x04 ++#define WL_PKTENG_PER_RX_WITH_ACK_START 0x05 ++#define WL_PKTENG_PER_TX_WITH_ACK_START 0x06 ++#define WL_PKTENG_PER_RX_STOP 0x08 ++#define WL_PKTENG_PER_MASK 0xff ++ ++#define WL_PKTENG_SYNCHRONOUS 0x100 /* synchronous flag */ ++ ++typedef struct wl_pkteng { ++ uint32 flags; ++ uint32 delay; /* Inter-packet delay */ ++ uint32 nframes; /* Number of frames */ ++ uint32 length; /* Packet length */ ++ uint8 seqno; /* Enable/disable sequence no. */ ++ struct ether_addr dest; /* Destination address */ ++ struct ether_addr src; /* Source address */ ++} wl_pkteng_t; ++ ++#define NUM_80211b_RATES 4 ++#define NUM_80211ag_RATES 8 ++#define NUM_80211n_RATES 32 ++#define NUM_80211_RATES (NUM_80211b_RATES+NUM_80211ag_RATES+NUM_80211n_RATES) ++typedef struct wl_pkteng_stats { ++ uint32 lostfrmcnt; /* RX PER test: no of frames lost (skip seqno) */ ++ int32 rssi; /* RSSI */ ++ int32 snr; /* signal to noise ratio */ ++ uint16 rxpktcnt[NUM_80211_RATES+1]; ++} wl_pkteng_stats_t; ++ ++typedef struct wl_sslpnphy_papd_debug_data { ++ uint8 psat_pwr; ++ uint8 psat_indx; ++ uint8 final_idx; ++ uint8 start_idx; ++ int32 min_phase; ++ int32 voltage; ++ int8 temperature; ++} wl_sslpnphy_papd_debug_data_t; ++typedef struct wl_sslpnphy_debug_data { ++ int16 papdcompRe [64]; ++ int16 papdcompIm [64]; ++} wl_sslpnphy_debug_data_t; ++typedef struct wl_sslpnphy_spbdump_data { ++ uint16 tbl_length; ++ int16 spbreal[256]; ++ int16 spbimg[256]; ++} wl_sslpnphy_spbdump_data_t; ++typedef struct wl_sslpnphy_percal_debug_data { ++ uint cur_idx; ++ uint tx_drift; ++ uint8 prev_cal_idx; ++ uint percal_ctr; ++ int nxt_cal_idx; ++ uint force_1idxcal; ++ uint onedxacl_req; ++ int32 last_cal_volt; ++ int8 last_cal_temp; ++ uint vbat_ripple; ++ uint exit_route; ++ int32 volt_winner; ++} wl_sslpnphy_percal_debug_data_t; ++ ++#define WL_WOWL_MAGIC (1 << 0) /* Wakeup on Magic packet */ ++#define WL_WOWL_NET (1 << 1) /* Wakeup on Netpattern */ ++#define WL_WOWL_DIS (1 << 2) /* Wakeup on loss-of-link due to Disassoc/Deauth */ ++#define WL_WOWL_RETR (1 << 3) /* Wakeup on retrograde TSF */ ++#define WL_WOWL_BCN (1 << 4) /* Wakeup on loss of beacon */ ++#define WL_WOWL_TST (1 << 5) /* Wakeup after test */ ++#define WL_WOWL_M1 (1 << 6) /* Wakeup after PTK refresh */ ++#define WL_WOWL_EAPID (1 << 7) /* Wakeup after receipt of EAP-Identity Req */ ++#define WL_WOWL_PME_GPIO (1 << 8) /* Wakeind via PME(0) or GPIO(1) */ ++#define WL_WOWL_NEEDTKIP1 (1 << 9) /* need tkip phase 1 key to be updated by the driver */ ++#define WL_WOWL_GTK_FAILURE (1 << 10) /* enable wakeup if GTK fails */ ++#define WL_WOWL_EXTMAGPAT (1 << 11) /* support extended magic packets */ ++#define WL_WOWL_ARPOFFLOAD (1 << 12) /* support ARP/NS/keepalive offloading */ ++#define WL_WOWL_WPA2 (1 << 13) /* read protocol version for EAPOL frames */ ++#define WL_WOWL_KEYROT (1 << 14) /* If the bit is set, use key rotaton */ ++#define WL_WOWL_BCAST (1 << 15) /* If the bit is set, frm received was bcast frame */ ++ ++#define MAGIC_PKT_MINLEN 102 /* Magic pkt min length is 6 * 0xFF + 16 * ETHER_ADDR_LEN */ ++ ++#define WOWL_PATTEN_TYPE_ARP (1 << 0) /* ARP offload Pattern */ ++#define WOWL_PATTEN_TYPE_NA (1 << 1) /* NA offload Pattern */ ++ ++typedef struct { ++ uint32 masksize; /* Size of the mask in #of bytes */ ++ uint32 offset; /* Offset to start looking for the packet in # of bytes */ ++ uint32 patternoffset; /* Offset of start of pattern in the structure */ ++ uint32 patternsize; /* Size of the pattern itself in #of bytes */ ++ uint32 id; /* id */ ++ uint32 reasonsize; /* Size of the wakeup reason code */ ++ uint32 flags; /* Flags to tell the pattern type and other properties */ ++ /* Mask follows the structure above */ ++ /* Pattern follows the mask is at 'patternoffset' from the start */ ++} wl_wowl_pattern_t; ++ ++typedef struct { ++ uint count; ++ wl_wowl_pattern_t pattern[1]; ++} wl_wowl_pattern_list_t; ++ ++typedef struct { ++ uint8 pci_wakeind; /* Whether PCI PMECSR PMEStatus bit was set */ ++ uint16 ucode_wakeind; /* What wakeup-event indication was set by ucode */ ++} wl_wowl_wakeind_t; ++ ++ ++/* per AC rate control related data structure */ ++typedef struct wl_txrate_class { ++ uint8 init_rate; ++ uint8 min_rate; ++ uint8 max_rate; ++} wl_txrate_class_t; ++ ++ ++/* Overlap BSS Scan parameters default, minimum, maximum */ ++#define WLC_OBSS_SCAN_PASSIVE_DWELL_DEFAULT 20 /* unit TU */ ++#define WLC_OBSS_SCAN_PASSIVE_DWELL_MIN 5 /* unit TU */ ++#define WLC_OBSS_SCAN_PASSIVE_DWELL_MAX 1000 /* unit TU */ ++#define WLC_OBSS_SCAN_ACTIVE_DWELL_DEFAULT 10 /* unit TU */ ++#define WLC_OBSS_SCAN_ACTIVE_DWELL_MIN 10 /* unit TU */ ++#define WLC_OBSS_SCAN_ACTIVE_DWELL_MAX 1000 /* unit TU */ ++#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_DEFAULT 300 /* unit Sec */ ++#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_MIN 10 /* unit Sec */ ++#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_MAX 900 /* unit Sec */ ++#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_DEFAULT 5 ++#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_MIN 5 ++#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_MAX 100 ++#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_DEFAULT 200 /* unit TU */ ++#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_MIN 200 /* unit TU */ ++#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_MAX 10000 /* unit TU */ ++#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_DEFAULT 20 /* unit TU */ ++#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_MIN 20 /* unit TU */ ++#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_MAX 10000 /* unit TU */ ++#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_DEFAULT 25 /* unit percent */ ++#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_MIN 0 /* unit percent */ ++#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_MAX 100 /* unit percent */ ++ ++/* structure for Overlap BSS scan arguments */ ++typedef struct wl_obss_scan_arg { ++ int16 passive_dwell; ++ int16 active_dwell; ++ int16 bss_widthscan_interval; ++ int16 passive_total; ++ int16 active_total; ++ int16 chanwidth_transition_delay; ++ int16 activity_threshold; ++} wl_obss_scan_arg_t; ++ ++#define WL_OBSS_SCAN_PARAM_LEN sizeof(wl_obss_scan_arg_t) ++#define WL_MIN_NUM_OBSS_SCAN_ARG 7 /* minimum number of arguments required for OBSS Scan */ ++ ++#define WL_COEX_INFO_MASK 0x07 ++#define WL_COEX_INFO_REQ 0x01 ++#define WL_COEX_40MHZ_INTOLERANT 0x02 ++#define WL_COEX_WIDTH20 0x04 ++ ++#define WLC_RSSI_INVALID 0 /* invalid RSSI value */ ++ ++#define MAX_RSSI_LEVELS 8 ++ ++/* RSSI event notification configuration. */ ++typedef struct wl_rssi_event { ++ uint32 rate_limit_msec; /* # of events posted to application will be limited to ++ * one per specified period (0 to disable rate limit). ++ */ ++ uint8 num_rssi_levels; /* Number of entries in rssi_levels[] below */ ++ int8 rssi_levels[MAX_RSSI_LEVELS]; /* Variable number of RSSI levels. An event ++ * will be posted each time the RSSI of received ++ * beacons/packets crosses a level. ++ */ ++} wl_rssi_event_t; ++ ++typedef struct wl_action_obss_coex_req { ++ uint8 info; ++ uint8 num; ++ uint8 ch_list[1]; ++} wl_action_obss_coex_req_t; ++ ++ ++/* IOVar parameter block for small MAC address array with type indicator */ ++#define WL_IOV_MAC_PARAM_LEN 4 ++ ++#define WL_IOV_PKTQ_LOG_PRECS 16 ++ ++typedef struct { ++ uint32 num_addrs; ++ char addr_type[WL_IOV_MAC_PARAM_LEN]; ++ struct ether_addr ea[WL_IOV_MAC_PARAM_LEN]; ++} wl_iov_mac_params_t; ++ ++ ++/* Parameter block for PKTQ_LOG statistics */ ++typedef struct { ++ uint32 requested; /* packets requested to be stored */ ++ uint32 stored; /* packets stored */ ++ uint32 saved; /* packets saved, ++ because a lowest priority queue has given away one packet ++ */ ++ uint32 selfsaved; /* packets saved, ++ because an older packet from the same queue has been dropped ++ */ ++ uint32 full_dropped; /* packets dropped, ++ because pktq is full with higher precedence packets ++ */ ++ uint32 dropped; /* packets dropped because pktq per that precedence is full */ ++ uint32 sacrificed; /* packets dropped, ++ in order to save one from a queue of a highest priority ++ */ ++ uint32 busy; /* packets droped because of hardware/transmission error */ ++ uint32 retry; /* packets re-sent because they were not received */ ++ uint32 ps_retry; /* packets retried again prior to moving power save mode */ ++ uint32 retry_drop; /* packets finally dropped after retry limit */ ++ uint32 max_avail; /* the high-water mark of the queue capacity for packets - ++ goes to zero as queue fills ++ */ ++ uint32 max_used; /* the high-water mark of the queue utilisation for packets - ++ increases with use ('inverse' of max_avail) ++ */ ++ uint32 queue_capacity; /* the maximum capacity of the queue */ ++} pktq_log_counters_v01_t; ++ ++#define sacrified sacrificed ++ ++typedef struct { ++ uint8 num_prec[WL_IOV_MAC_PARAM_LEN]; ++ pktq_log_counters_v01_t counters[WL_IOV_MAC_PARAM_LEN][WL_IOV_PKTQ_LOG_PRECS]; ++ char headings[1]; ++} pktq_log_format_v01_t; ++ ++ ++typedef struct { ++ uint32 version; ++ wl_iov_mac_params_t params; ++ union { ++ pktq_log_format_v01_t v01; ++ } pktq_log; ++} wl_iov_pktq_log_t; ++ ++ ++/* **** EXTLOG **** */ ++#define EXTLOG_CUR_VER 0x0100 ++ ++#define MAX_ARGSTR_LEN 18 /* At least big enough for storing ETHER_ADDR_STR_LEN */ ++ ++/* log modules (bitmap) */ ++#define LOG_MODULE_COMMON 0x0001 ++#define LOG_MODULE_ASSOC 0x0002 ++#define LOG_MODULE_EVENT 0x0004 ++#define LOG_MODULE_MAX 3 /* Update when adding module */ ++ ++/* log levels */ ++#define WL_LOG_LEVEL_DISABLE 0 ++#define WL_LOG_LEVEL_ERR 1 ++#define WL_LOG_LEVEL_WARN 2 ++#define WL_LOG_LEVEL_INFO 3 ++#define WL_LOG_LEVEL_MAX WL_LOG_LEVEL_INFO /* Update when adding level */ ++ ++/* flag */ ++#define LOG_FLAG_EVENT 1 ++ ++/* log arg_type */ ++#define LOG_ARGTYPE_NULL 0 ++#define LOG_ARGTYPE_STR 1 /* %s */ ++#define LOG_ARGTYPE_INT 2 /* %d */ ++#define LOG_ARGTYPE_INT_STR 3 /* %d...%s */ ++#define LOG_ARGTYPE_STR_INT 4 /* %s...%d */ ++ ++typedef struct wlc_extlog_cfg { ++ int max_number; ++ uint16 module; /* bitmap */ ++ uint8 level; ++ uint8 flag; ++ uint16 version; ++} wlc_extlog_cfg_t; ++ ++typedef struct log_record { ++ uint32 time; ++ uint16 module; ++ uint16 id; ++ uint8 level; ++ uint8 sub_unit; ++ uint8 seq_num; ++ int32 arg; ++ char str[MAX_ARGSTR_LEN]; ++} log_record_t; ++ ++typedef struct wlc_extlog_req { ++ uint32 from_last; ++ uint32 num; ++} wlc_extlog_req_t; ++ ++typedef struct wlc_extlog_results { ++ uint16 version; ++ uint16 record_len; ++ uint32 num; ++ log_record_t logs[1]; ++} wlc_extlog_results_t; ++ ++typedef struct log_idstr { ++ uint16 id; ++ uint16 flag; ++ uint8 arg_type; ++ const char *fmt_str; ++} log_idstr_t; ++ ++#define FMTSTRF_USER 1 ++ ++/* flat ID definitions ++ * New definitions HAVE TO BE ADDED at the end of the table. Otherwise, it will ++ * affect backward compatibility with pre-existing apps ++ */ ++typedef enum { ++ FMTSTR_DRIVER_UP_ID = 0, ++ FMTSTR_DRIVER_DOWN_ID = 1, ++ FMTSTR_SUSPEND_MAC_FAIL_ID = 2, ++ FMTSTR_NO_PROGRESS_ID = 3, ++ FMTSTR_RFDISABLE_ID = 4, ++ FMTSTR_REG_PRINT_ID = 5, ++ FMTSTR_EXPTIME_ID = 6, ++ FMTSTR_JOIN_START_ID = 7, ++ FMTSTR_JOIN_COMPLETE_ID = 8, ++ FMTSTR_NO_NETWORKS_ID = 9, ++ FMTSTR_SECURITY_MISMATCH_ID = 10, ++ FMTSTR_RATE_MISMATCH_ID = 11, ++ FMTSTR_AP_PRUNED_ID = 12, ++ FMTSTR_KEY_INSERTED_ID = 13, ++ FMTSTR_DEAUTH_ID = 14, ++ FMTSTR_DISASSOC_ID = 15, ++ FMTSTR_LINK_UP_ID = 16, ++ FMTSTR_LINK_DOWN_ID = 17, ++ FMTSTR_RADIO_HW_OFF_ID = 18, ++ FMTSTR_RADIO_HW_ON_ID = 19, ++ FMTSTR_EVENT_DESC_ID = 20, ++ FMTSTR_PNP_SET_POWER_ID = 21, ++ FMTSTR_RADIO_SW_OFF_ID = 22, ++ FMTSTR_RADIO_SW_ON_ID = 23, ++ FMTSTR_PWD_MISMATCH_ID = 24, ++ FMTSTR_FATAL_ERROR_ID = 25, ++ FMTSTR_AUTH_FAIL_ID = 26, ++ FMTSTR_ASSOC_FAIL_ID = 27, ++ FMTSTR_IBSS_FAIL_ID = 28, ++ FMTSTR_EXTAP_FAIL_ID = 29, ++ FMTSTR_MAX_ID ++} log_fmtstr_id_t; ++ ++#ifdef DONGLEOVERLAYS ++typedef struct { ++ uint32 flags_idx; /* lower 8 bits: overlay index; upper 24 bits: flags */ ++ uint32 offset; /* offset into overlay region to write code */ ++ uint32 len; /* overlay code len */ ++ /* overlay code follows this struct */ ++} wl_ioctl_overlay_t; ++ ++#define OVERLAY_IDX_MASK 0x000000ff ++#define OVERLAY_IDX_SHIFT 0 ++#define OVERLAY_FLAGS_MASK 0xffffff00 ++#define OVERLAY_FLAGS_SHIFT 8 ++/* overlay written to device memory immediately after loading the base image */ ++#define OVERLAY_FLAG_POSTLOAD 0x100 ++/* defer overlay download until the device responds w/WLC_E_OVL_DOWNLOAD event */ ++#define OVERLAY_FLAG_DEFER_DL 0x200 ++/* overlay downloaded prior to the host going to sleep */ ++#define OVERLAY_FLAG_PRESLEEP 0x400 ++ ++#define OVERLAY_DOWNLOAD_CHUNKSIZE 1024 ++#endif /* DONGLEOVERLAYS */ ++ ++/* no default structure packing */ ++#include ++ ++/* require strict packing */ ++#include ++/* Structures and constants used for "vndr_ie" IOVar interface */ ++#define VNDR_IE_CMD_LEN 4 /* length of the set command string: ++ * "add", "del" (+ NUL) ++ */ ++ ++/* 802.11 Mgmt Packet flags */ ++#define VNDR_IE_BEACON_FLAG 0x1 ++#define VNDR_IE_PRBRSP_FLAG 0x2 ++#define VNDR_IE_ASSOCRSP_FLAG 0x4 ++#define VNDR_IE_AUTHRSP_FLAG 0x8 ++#define VNDR_IE_PRBREQ_FLAG 0x10 ++#define VNDR_IE_ASSOCREQ_FLAG 0x20 ++#define VNDR_IE_IWAPID_FLAG 0x40 /* vendor IE in IW advertisement protocol ID field */ ++#define VNDR_IE_CUSTOM_FLAG 0x100 /* allow custom IE id */ ++ ++#define VNDR_IE_INFO_HDR_LEN (sizeof(uint32)) ++ ++typedef BWL_PRE_PACKED_STRUCT struct { ++ uint32 pktflag; /* bitmask indicating which packet(s) contain this IE */ ++ vndr_ie_t vndr_ie_data; /* vendor IE data */ ++} BWL_POST_PACKED_STRUCT vndr_ie_info_t; ++ ++typedef BWL_PRE_PACKED_STRUCT struct { ++ int iecount; /* number of entries in the vndr_ie_list[] array */ ++ vndr_ie_info_t vndr_ie_list[1]; /* variable size list of vndr_ie_info_t structs */ ++} BWL_POST_PACKED_STRUCT vndr_ie_buf_t; ++ ++typedef BWL_PRE_PACKED_STRUCT struct { ++ char cmd[VNDR_IE_CMD_LEN]; /* vndr_ie IOVar set command : "add", "del" + NUL */ ++ vndr_ie_buf_t vndr_ie_buffer; /* buffer containing Vendor IE list information */ ++} BWL_POST_PACKED_STRUCT vndr_ie_setbuf_t; ++ ++/* tag_ID/length/value_buffer tuple */ ++typedef BWL_PRE_PACKED_STRUCT struct { ++ uint8 id; ++ uint8 len; ++ uint8 data[1]; ++} BWL_POST_PACKED_STRUCT tlv_t; ++ ++typedef BWL_PRE_PACKED_STRUCT struct { ++ uint32 pktflag; /* bitmask indicating which packet(s) contain this IE */ ++ tlv_t ie_data; /* IE data */ ++} BWL_POST_PACKED_STRUCT ie_info_t; ++ ++typedef BWL_PRE_PACKED_STRUCT struct { ++ int iecount; /* number of entries in the ie_list[] array */ ++ ie_info_t ie_list[1]; /* variable size list of ie_info_t structs */ ++} BWL_POST_PACKED_STRUCT ie_buf_t; ++ ++typedef BWL_PRE_PACKED_STRUCT struct { ++ char cmd[VNDR_IE_CMD_LEN]; /* ie IOVar set command : "add" + NUL */ ++ ie_buf_t ie_buffer; /* buffer containing IE list information */ ++} BWL_POST_PACKED_STRUCT ie_setbuf_t; ++ ++typedef BWL_PRE_PACKED_STRUCT struct { ++ uint32 pktflag; /* bitmask indicating which packet(s) contain this IE */ ++ uint8 id; /* IE type */ ++} BWL_POST_PACKED_STRUCT ie_getbuf_t; ++ ++/* structures used to define format of wps ie data from probe requests */ ++/* passed up to applications via iovar "prbreq_wpsie" */ ++typedef BWL_PRE_PACKED_STRUCT struct sta_prbreq_wps_ie_hdr { ++ struct ether_addr staAddr; ++ uint16 ieLen; ++} BWL_POST_PACKED_STRUCT sta_prbreq_wps_ie_hdr_t; ++ ++typedef BWL_PRE_PACKED_STRUCT struct sta_prbreq_wps_ie_data { ++ sta_prbreq_wps_ie_hdr_t hdr; ++ uint8 ieData[1]; ++} BWL_POST_PACKED_STRUCT sta_prbreq_wps_ie_data_t; ++ ++typedef BWL_PRE_PACKED_STRUCT struct sta_prbreq_wps_ie_list { ++ uint32 totLen; ++ uint8 ieDataList[1]; ++} BWL_POST_PACKED_STRUCT sta_prbreq_wps_ie_list_t; ++ ++ ++#ifdef WLMEDIA_TXFAILEVENT ++typedef BWL_PRE_PACKED_STRUCT struct { ++ char dest[ETHER_ADDR_LEN]; /* destination MAC */ ++ uint8 prio; /* Packet Priority */ ++ uint8 flags; /* Flags */ ++ uint32 tsf_l; /* TSF timer low */ ++ uint32 tsf_h; /* TSF timer high */ ++ uint16 rates; /* Main Rates */ ++ uint16 txstatus; /* TX Status */ ++} BWL_POST_PACKED_STRUCT txfailinfo_t; ++#endif /* WLMEDIA_TXFAILEVENT */ ++ ++/* no strict structure packing */ ++#include ++ ++/* Global ASSERT Logging */ ++#define ASSERTLOG_CUR_VER 0x0100 ++#define MAX_ASSRTSTR_LEN 64 ++ ++typedef struct assert_record { ++ uint32 time; ++ uint8 seq_num; ++ char str[MAX_ASSRTSTR_LEN]; ++} assert_record_t; ++ ++typedef struct assertlog_results { ++ uint16 version; ++ uint16 record_len; ++ uint32 num; ++ assert_record_t logs[1]; ++} assertlog_results_t; ++ ++#define LOGRRC_FIX_LEN 8 ++#define IOBUF_ALLOWED_NUM_OF_LOGREC(type, len) ((len - LOGRRC_FIX_LEN)/sizeof(type)) ++ ++ ++/* channel interference measurement (chanim) related defines */ ++ ++/* chanim mode */ ++#define CHANIM_DISABLE 0 /* disabled */ ++#define CHANIM_DETECT 1 /* detection only */ ++#define CHANIM_EXT 2 /* external state machine */ ++#define CHANIM_ACT 3 /* full internal state machine, detect + act */ ++#define CHANIM_MODE_MAX 4 ++ ++/* define for apcs reason code */ ++#define APCS_INIT 0 ++#define APCS_IOCTL 1 ++#define APCS_CHANIM 2 ++#define APCS_CSTIMER 3 ++#define APCS_BTA 4 ++ ++/* number of ACS record entries */ ++#define CHANIM_ACS_RECORD 10 ++ ++/* CHANIM */ ++#define CCASTATS_TXDUR 0 ++#define CCASTATS_INBSS 1 ++#define CCASTATS_OBSS 2 ++#define CCASTATS_NOCTG 3 ++#define CCASTATS_NOPKT 4 ++#define CCASTATS_DOZE 5 ++#define CCASTATS_TXOP 6 ++#define CCASTATS_GDTXDUR 7 ++#define CCASTATS_BDTXDUR 8 ++#define CCASTATS_MAX 9 ++ ++/* chanim acs record */ ++typedef struct { ++ bool valid; ++ uint8 trigger; ++ chanspec_t selected_chspc; ++ int8 bgnoise; ++ uint32 glitch_cnt; ++ uint8 ccastats; ++ uint timestamp; ++} chanim_acs_record_t; ++ ++typedef struct { ++ chanim_acs_record_t acs_record[CHANIM_ACS_RECORD]; ++ uint8 count; ++ uint timestamp; ++} wl_acs_record_t; ++ ++typedef struct chanim_stats { ++ uint32 glitchcnt; /* normalized as per second count */ ++ uint32 badplcp; /* normalized as per second count */ ++ uint8 ccastats[CCASTATS_MAX]; /* normalized as 0-255 */ ++ int8 bgnoise; /* background noise level (in dBm) */ ++ chanspec_t chanspec; ++ uint32 timestamp; ++} chanim_stats_t; ++ ++#define WL_CHANIM_STATS_VERSION 1 ++#define WL_CHANIM_COUNT_ALL 0xff ++#define WL_CHANIM_COUNT_ONE 0x1 ++ ++typedef struct { ++ uint32 buflen; ++ uint32 version; ++ uint32 count; ++ chanim_stats_t stats[1]; ++} wl_chanim_stats_t; ++ ++#define WL_CHANIM_STATS_FIXED_LEN OFFSETOF(wl_chanim_stats_t, stats) ++ ++/* Noise measurement metrics. */ ++#define NOISE_MEASURE_KNOISE 0x1 ++ ++/* scb probe parameter */ ++typedef struct { ++ uint32 scb_timeout; ++ uint32 scb_activity_time; ++ uint32 scb_max_probe; ++} wl_scb_probe_t; ++ ++/* ap tpc modes */ ++#define AP_TPC_OFF 0 ++#define AP_TPC_BSS_PWR 1 /* BSS power control */ ++#define AP_TPC_AP_PWR 2 /* AP power control */ ++#define AP_TPC_AP_BSS_PWR 3 /* Both AP and BSS power control */ ++#define AP_TPC_MAX_LINK_MARGIN 127 ++ ++/* structure/defines for selective mgmt frame (smf) stats support */ ++ ++#define SMFS_VERSION 1 ++/* selected mgmt frame (smf) stats element */ ++typedef struct wl_smfs_elem { ++ uint32 count; ++ uint16 code; /* SC or RC code */ ++} wl_smfs_elem_t; ++ ++typedef struct wl_smf_stats { ++ uint32 version; ++ uint16 length; /* reserved for future usage */ ++ uint8 type; ++ uint8 codetype; ++ uint32 ignored_cnt; ++ uint32 malformed_cnt; ++ uint32 count_total; /* count included the interested group */ ++ wl_smfs_elem_t elem[1]; ++} wl_smf_stats_t; ++ ++#define WL_SMFSTATS_FIXED_LEN OFFSETOF(wl_smf_stats_t, elem); ++ ++enum { ++ SMFS_CODETYPE_SC, ++ SMFS_CODETYPE_RC ++}; ++ ++/* reuse two number in the sc/rc space */ ++#define SMFS_CODE_MALFORMED 0xFFFE ++#define SMFS_CODE_IGNORED 0xFFFD ++ ++typedef enum smfs_type { ++ SMFS_TYPE_AUTH, ++ SMFS_TYPE_ASSOC, ++ SMFS_TYPE_REASSOC, ++ SMFS_TYPE_DISASSOC_TX, ++ SMFS_TYPE_DISASSOC_RX, ++ SMFS_TYPE_DEAUTH_TX, ++ SMFS_TYPE_DEAUTH_RX, ++ SMFS_TYPE_MAX ++} smfs_type_t; ++ ++#ifdef PHYMON ++ ++#define PHYMON_VERSION 1 ++ ++typedef struct wl_phycal_core_state { ++ /* Tx IQ/LO calibration coeffs */ ++ int16 tx_iqlocal_a; ++ int16 tx_iqlocal_b; ++ int8 tx_iqlocal_ci; ++ int8 tx_iqlocal_cq; ++ int8 tx_iqlocal_di; ++ int8 tx_iqlocal_dq; ++ int8 tx_iqlocal_ei; ++ int8 tx_iqlocal_eq; ++ int8 tx_iqlocal_fi; ++ int8 tx_iqlocal_fq; ++ ++ /* Rx IQ calibration coeffs */ ++ int16 rx_iqcal_a; ++ int16 rx_iqcal_b; ++ ++ uint8 tx_iqlocal_pwridx; /* Tx Power Index for Tx IQ/LO calibration */ ++ uint32 papd_epsilon_table[64]; /* PAPD epsilon table */ ++ int16 papd_epsilon_offset; /* PAPD epsilon offset */ ++ uint8 curr_tx_pwrindex; /* Tx power index */ ++ int8 idle_tssi; /* Idle TSSI */ ++ int8 est_tx_pwr; /* Estimated Tx Power (dB) */ ++ int8 est_rx_pwr; /* Estimated Rx Power (dB) from RSSI */ ++ uint16 rx_gaininfo; /* Rx gain applied on last Rx pkt */ ++ uint16 init_gaincode; /* initgain required for ACI */ ++ int8 estirr_tx; ++ int8 estirr_rx; ++ ++} wl_phycal_core_state_t; ++ ++typedef struct wl_phycal_state { ++ int version; ++ int8 num_phy_cores; /* number of cores */ ++ int8 curr_temperature; /* on-chip temperature sensor reading */ ++ chanspec_t chspec; /* channspec for this state */ ++ bool aci_state; /* ACI state: ON/OFF */ ++ uint16 crsminpower; /* crsminpower required for ACI */ ++ uint16 crsminpowerl; /* crsminpowerl required for ACI */ ++ uint16 crsminpoweru; /* crsminpoweru required for ACI */ ++ wl_phycal_core_state_t phycal_core[1]; ++} wl_phycal_state_t; ++ ++#define WL_PHYCAL_STAT_FIXED_LEN OFFSETOF(wl_phycal_state_t, phycal_core) ++#endif /* PHYMON */ ++ ++/* discovery state */ ++typedef struct wl_p2p_disc_st { ++ uint8 state; /* see state */ ++ chanspec_t chspec; /* valid in listen state */ ++ uint16 dwell; /* valid in listen state, in ms */ ++} wl_p2p_disc_st_t; ++ ++/* state */ ++#define WL_P2P_DISC_ST_SCAN 0 ++#define WL_P2P_DISC_ST_LISTEN 1 ++#define WL_P2P_DISC_ST_SEARCH 2 ++ ++/* scan request */ ++typedef struct wl_p2p_scan { ++ uint8 type; /* 'S' for WLC_SCAN, 'E' for "escan" */ ++ uint8 reserved[3]; ++ /* scan or escan parms... */ ++} wl_p2p_scan_t; ++ ++/* i/f request */ ++typedef struct wl_p2p_if { ++ struct ether_addr addr; ++ uint8 type; /* see i/f type */ ++ chanspec_t chspec; /* for p2p_ifadd GO */ ++} wl_p2p_if_t; ++ ++/* i/f type */ ++#define WL_P2P_IF_CLIENT 0 ++#define WL_P2P_IF_GO 1 ++#define WL_P2P_IF_DYNBCN_GO 2 ++#define WL_P2P_IF_DEV 3 ++ ++/* i/f query */ ++typedef struct wl_p2p_ifq { ++ uint bsscfgidx; ++ char ifname[BCM_MSG_IFNAME_MAX]; ++} wl_p2p_ifq_t; ++ ++/* OppPS & CTWindow */ ++typedef struct wl_p2p_ops { ++ uint8 ops; /* 0: disable 1: enable */ ++ uint8 ctw; /* >= 10 */ ++} wl_p2p_ops_t; ++ ++/* absence and presence request */ ++typedef struct wl_p2p_sched_desc { ++ uint32 start; ++ uint32 interval; ++ uint32 duration; ++ uint32 count; /* see count */ ++} wl_p2p_sched_desc_t; ++ ++/* count */ ++#define WL_P2P_SCHED_RSVD 0 ++#define WL_P2P_SCHED_REPEAT 255 /* anything > 255 will be treated as 255 */ ++ ++typedef struct wl_p2p_sched { ++ uint8 type; /* see schedule type */ ++ uint8 action; /* see schedule action */ ++ uint8 option; /* see schedule option */ ++ wl_p2p_sched_desc_t desc[1]; ++} wl_p2p_sched_t; ++#define WL_P2P_SCHED_FIXED_LEN 3 ++ ++/* schedule type */ ++#define WL_P2P_SCHED_TYPE_ABS 0 /* Scheduled Absence */ ++#define WL_P2P_SCHED_TYPE_REQ_ABS 1 /* Requested Absence */ ++ ++/* schedule action during absence periods (for WL_P2P_SCHED_ABS type) */ ++#define WL_P2P_SCHED_ACTION_NONE 0 /* no action */ ++#define WL_P2P_SCHED_ACTION_DOZE 1 /* doze */ ++/* schedule option - WL_P2P_SCHED_TYPE_REQ_ABS */ ++#define WL_P2P_SCHED_ACTION_GOOFF 2 /* turn off GO beacon/prbrsp functions */ ++/* schedule option - WL_P2P_SCHED_TYPE_XXX */ ++#define WL_P2P_SCHED_ACTION_RESET 255 /* reset */ ++ ++/* schedule option - WL_P2P_SCHED_TYPE_ABS */ ++#define WL_P2P_SCHED_OPTION_NORMAL 0 /* normal start/interval/duration/count */ ++#define WL_P2P_SCHED_OPTION_BCNPCT 1 /* percentage of beacon interval */ ++/* schedule option - WL_P2P_SCHED_TYPE_REQ_ABS */ ++#define WL_P2P_SCHED_OPTION_TSFOFS 2 /* normal start/internal/duration/count with ++ * start being an offset of the 'current' TSF ++ */ ++ ++/* feature flags */ ++#define WL_P2P_FEAT_GO_CSA (1 << 0) /* GO moves with the STA using CSA method */ ++#define WL_P2P_FEAT_GO_NOLEGACY (1 << 1) /* GO does not probe respond to non-p2p probe ++ * requests ++ */ ++#define WL_P2P_FEAT_RESTRICT_DEV_RESP (1 << 2) /* Restrict p2p dev interface from responding */ ++ ++/* RFAWARE def */ ++#define BCM_ACTION_RFAWARE 0x77 ++#define BCM_ACTION_RFAWARE_DCS 0x01 ++ ++/* DCS reason code define */ ++#define BCM_DCS_IOVAR 0x1 ++#define BCM_DCS_UNKNOWN 0xFF ++ ++typedef struct wl_bcmdcs_data { ++ uint reason; ++ chanspec_t chspec; ++} wl_bcmdcs_data_t; ++ ++/* n-mode support capability */ ++/* 2x2 includes both 1x1 & 2x2 devices ++ * reserved #define 2 for future when we want to separate 1x1 & 2x2 and ++ * control it independently ++ */ ++#define WL_11N_2x2 1 ++#define WL_11N_3x3 3 ++#define WL_11N_4x4 4 ++ ++/* define 11n feature disable flags */ ++#define WLFEATURE_DISABLE_11N 0x00000001 ++#define WLFEATURE_DISABLE_11N_STBC_TX 0x00000002 ++#define WLFEATURE_DISABLE_11N_STBC_RX 0x00000004 ++#define WLFEATURE_DISABLE_11N_SGI_TX 0x00000008 ++#define WLFEATURE_DISABLE_11N_SGI_RX 0x00000010 ++#define WLFEATURE_DISABLE_11N_AMPDU_TX 0x00000020 ++#define WLFEATURE_DISABLE_11N_AMPDU_RX 0x00000040 ++#define WLFEATURE_DISABLE_11N_GF 0x00000080 ++ ++/* Proxy STA modes */ ++#define PSTA_MODE_DISABLED 0 ++#define PSTA_MODE_PROXY 1 ++#define PSTA_MODE_REPEATER 2 ++ ++ ++/* NAT configuration */ ++typedef struct { ++ uint32 ipaddr; /* interface ip address */ ++ uint32 ipaddr_mask; /* interface ip address mask */ ++ uint32 ipaddr_gateway; /* gateway ip address */ ++ uint8 mac_gateway[6]; /* gateway mac address */ ++ uint32 ipaddr_dns; /* DNS server ip address, valid only for public if */ ++ uint8 mac_dns[6]; /* DNS server mac address, valid only for public if */ ++ uint8 GUID[38]; /* interface GUID */ ++} nat_if_info_t; ++ ++typedef struct { ++ uint op; /* operation code */ ++ bool pub_if; /* set for public if, clear for private if */ ++ nat_if_info_t if_info; /* interface info */ ++} nat_cfg_t; ++ ++/* op code in nat_cfg */ ++#define NAT_OP_ENABLE 1 /* enable NAT on given interface */ ++#define NAT_OP_DISABLE 2 /* disable NAT on given interface */ ++#define NAT_OP_DISABLE_ALL 3 /* disable NAT on all interfaces */ ++ ++/* NAT state */ ++#define NAT_STATE_ENABLED 1 /* NAT is enabled */ ++#define NAT_STATE_DISABLED 2 /* NAT is disabled */ ++ ++typedef struct { ++ int state; /* NAT state returned */ ++} nat_state_t; ++ ++#ifdef PROP_TXSTATUS ++/* Bit definitions for tlv iovar */ ++/* ++ * enable RSSI signals: ++ * WLFC_CTL_TYPE_RSSI ++ */ ++#define WLFC_FLAGS_RSSI_SIGNALS 1 ++ ++/* enable (if/mac_open, if/mac_close,, mac_add, mac_del) signals: ++ * ++ * WLFC_CTL_TYPE_MAC_OPEN ++ * WLFC_CTL_TYPE_MAC_CLOSE ++ * ++ * WLFC_CTL_TYPE_INTERFACE_OPEN ++ * WLFC_CTL_TYPE_INTERFACE_CLOSE ++ * ++ * WLFC_CTL_TYPE_MACDESC_ADD ++ * WLFC_CTL_TYPE_MACDESC_DEL ++ * ++ */ ++#define WLFC_FLAGS_XONXOFF_SIGNALS 2 ++ ++/* enable (status, fifo_credit, mac_credit) signals ++ * WLFC_CTL_TYPE_MAC_REQUEST_CREDIT ++ * WLFC_CTL_TYPE_TXSTATUS ++ * WLFC_CTL_TYPE_FIFO_CREDITBACK ++ */ ++#define WLFC_FLAGS_CREDIT_STATUS_SIGNALS 4 ++ ++#define WLFC_FLAGS_HOST_PROPTXSTATUS_ACTIVE 8 ++#define WLFC_FLAGS_PSQ_GENERATIONFSM_ENABLE 16 ++#define WLFC_FLAGS_PSQ_ZERO_BUFFER_ENABLE 32 ++#endif /* PROP_TXSTATUS */ ++ ++#define BTA_STATE_LOG_SZ 64 ++ ++/* BTAMP Statemachine states */ ++enum { ++ HCIReset = 1, ++ HCIReadLocalAMPInfo, ++ HCIReadLocalAMPASSOC, ++ HCIWriteRemoteAMPASSOC, ++ HCICreatePhysicalLink, ++ HCIAcceptPhysicalLinkRequest, ++ HCIDisconnectPhysicalLink, ++ HCICreateLogicalLink, ++ HCIAcceptLogicalLink, ++ HCIDisconnectLogicalLink, ++ HCILogicalLinkCancel, ++ HCIAmpStateChange, ++ HCIWriteLogicalLinkAcceptTimeout ++}; ++ ++typedef struct flush_txfifo { ++ uint32 txfifobmp; ++ uint32 hwtxfifoflush; ++ struct ether_addr ea; ++} flush_txfifo_t; ++ ++#define CHANNEL_5G_LOW_START 36 /* 5G low (36..48) CDD enable/disable bit mask */ ++#define CHANNEL_5G_MID_START 52 /* 5G mid (52..64) CDD enable/disable bit mask */ ++#define CHANNEL_5G_HIGH_START 100 /* 5G high (100..140) CDD enable/disable bit mask */ ++#define CHANNEL_5G_UPPER_START 149 /* 5G upper (149..161) CDD enable/disable bit mask */ ++ ++enum { ++ SPATIAL_MODE_2G_IDX = 0, ++ SPATIAL_MODE_5G_LOW_IDX, ++ SPATIAL_MODE_5G_MID_IDX, ++ SPATIAL_MODE_5G_HIGH_IDX, ++ SPATIAL_MODE_5G_UPPER_IDX, ++ SPATIAL_MODE_MAX_IDX ++}; ++ ++/* IOVAR "mempool" parameter. Used to retrieve a list of memory pool statistics. */ ++typedef struct wl_mempool_stats { ++ int num; /* Number of memory pools */ ++ bcm_mp_stats_t s[1]; /* Variable array of memory pool stats. */ ++} wl_mempool_stats_t; ++ ++/* Network Offload Engine */ ++#define NWOE_OL_ENABLE 0x00000001 ++ ++typedef struct { ++ uint32 ipaddr; ++ uint32 ipaddr_netmask; ++ uint32 ipaddr_gateway; ++} nwoe_ifconfig_t; ++ ++/* ++ * Traffic management structures/defines. ++ */ ++ ++/* Traffic management bandwidth parameters */ ++#define TRF_MGMT_MAX_PRIORITIES 3 ++ ++#define TRF_MGMT_FLAG_ADD_DSCP 0x0001 /* Add DSCP to IP TOS field */ ++#define TRF_MGMT_FLAG_DISABLE_SHAPING 0x0002 /* Only support traffic clasification */ ++ ++ ++/* Traffic management priority classes */ ++typedef enum trf_mgmt_priority_class { ++ trf_mgmt_priority_low = 0, /* Maps to 802.1p BK */ ++ trf_mgmt_priority_medium = 1, /* Maps to 802.1p BE */ ++ trf_mgmt_priority_high = 2, /* Maps to 802.1p VI */ ++ trf_mgmt_priority_invalid = (trf_mgmt_priority_high + 1) ++} trf_mgmt_priority_class_t; ++ ++/* Traffic management configuration parameters */ ++typedef struct trf_mgmt_config { ++ uint32 trf_mgmt_enabled; /* 0 - disabled, 1 - enabled */ ++ uint32 flags; /* See TRF_MGMT_FLAG_xxx defines */ ++ uint32 host_ip_addr; ++ uint32 host_subnet_mask; ++ uint32 downlink_bandwidth; /* In units of kbps */ ++ uint32 uplink_bandwidth; /* In units of kbps */ ++ uint32 min_tx_bandwidth[TRF_MGMT_MAX_PRIORITIES]; ++ uint32 min_rx_bandwidth[TRF_MGMT_MAX_PRIORITIES]; ++} trf_mgmt_config_t; ++ ++/* Traffic management filter */ ++typedef struct trf_mgmt_filter { ++ uint32 dst_ip_addr; /* His IP address */ ++ uint16 dst_port; /* His L4 port */ ++ uint16 src_port; /* My L4 port */ ++ uint16 prot; /* L4 protocol (only TCP or UDP protocols) */ ++ uint16 flags; /* TBD. For now, this must be zero. */ ++ trf_mgmt_priority_class_t priority; /* 802.1p priority for filtered packets */ ++} trf_mgmt_filter_t; ++ ++/* Traffic management filter list (variable length) */ ++typedef struct trf_mgmt_filter_list { ++ uint32 num_filters; ++ trf_mgmt_filter_t filter[1]; ++} trf_mgmt_filter_list_t; ++ ++/* Traffic management shaping info */ ++typedef struct trf_mgmt_shaping_info { ++ uint32 max_bps; /* Max bytes consumed or produced per second */ ++ uint32 max_bytes_per_sampling_period; /* Max bytes consumed or produced per sample */ ++ uint32 shaping_delay_threshold; /* Theshold for starting traffic delays */ ++ uint32 num_bytes_produced_per_sec; /* Bytes produced over the sampling period */ ++ uint32 num_bytes_consumed_per_sec; /* Bytes consumed over the sampling period */ ++} trf_mgmt_shaping_info_t; ++ ++/* Traffic management shaping info array */ ++typedef struct trf_mgmt_shaping_info_array { ++ trf_mgmt_shaping_info_t tx_queue_shaping_info[TRF_MGMT_MAX_PRIORITIES]; ++ trf_mgmt_shaping_info_t rx_queue_shaping_info[TRF_MGMT_MAX_PRIORITIES]; ++} trf_mgmt_shaping_info_array_t; ++ ++ ++/* Traffic management statistical counters */ ++typedef struct trf_mgmt_stats { ++ uint32 num_processed_packets; /* Number of packets processed */ ++ uint32 num_processed_bytes; /* Number of bytes processed */ ++ uint32 num_queued_packets; /* Number of packets in queue */ ++ uint32 num_queued_bytes; /* Number of bytes in queue */ ++ uint32 num_discarded_packets; /* Number of packets discarded from queue */ ++} trf_mgmt_stats_t; ++ ++/* Traffic management statisics array */ ++typedef struct trf_mgmt_stats_array { ++ trf_mgmt_stats_t tx_queue_stats[TRF_MGMT_MAX_PRIORITIES]; ++ trf_mgmt_stats_t rx_queue_stats[TRF_MGMT_MAX_PRIORITIES]; ++} trf_mgmt_stats_array_t; ++ ++#endif /* _wlioctl_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/aiutils.c b/drivers/net/ethernet/broadcom/gmac/src/shared/aiutils.c +--- a/drivers/net/ethernet/broadcom/gmac/src/shared/aiutils.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/shared/aiutils.c 2017-11-09 17:53:44.023292000 +0800 +@@ -0,0 +1,1028 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ * ++ * Misc utility routines for accessing chip-specific features ++ * of the SiliconBackplane-based Broadcom chips. ++ * ++ * $Id: aiutils.c 327582 2012-04-14 05:02:37Z kenlo $ ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "siutils_priv.h" ++#if defined(CONFIG_MACH_HX4) ++#include "hx4_erom.h" ++#elif defined(CONFIG_MACH_HR2) ++#include "hr2_erom.h" ++#elif defined(CONFIG_MACH_KT2) ++#include "kt2_erom.h" ++#elif defined(CONFIG_MACH_GH) ++#include "gh_erom.h" ++#elif defined(CONFIG_MACH_SB2) ++#include "sb2_erom.h" ++#elif defined(CONFIG_MACH_HR3) ++#include "hr3_erom.h" ++#elif defined(CONFIG_MACH_GH2) ++#include "gh2_erom.h" ++#endif ++ ++/* EROM parsing */ ++static uint32 ++get_erom_ent(si_t *sih, uint32 **eromptr, uint32 mask, uint32 match) ++{ ++ uint32 ent; ++ uint inv = 0, nom = 0; ++ ++ while (TRUE) { ++ ent = **eromptr; ++ ++ (*eromptr)++; ++ ++ if (mask == 0) { ++ break; ++ } ++ ++ if ((ent & ER_VALID) == 0) { ++ inv++; ++ continue; ++ } ++ ++ if (ent == (ER_END | ER_VALID)) { ++ break; ++ } ++ ++ if ((ent & mask) == match) { ++ break; ++ } ++ ++ nom++; ++ } ++ ++ SI_VMSG(("%s: Returning ent 0x%08x\n", __FUNCTION__, ent)); ++ if (inv + nom) { ++ SI_VMSG((" after %d invalid and %d non-matching entries\n", inv, nom)); ++ } ++ return ent; ++} ++ ++static uint32 ++get_asd(si_t *sih, uint32 **eromptr, uint sp, uint ad, uint st, uint32 *addrl, uint32 *addrh, ++ uint32 *sizel, uint32 *sizeh) ++{ ++ uint32 asd, sz, szd; ++ ++ asd = get_erom_ent(sih, eromptr, ER_VALID, ER_VALID); ++ if (((asd & ER_TAG1) != ER_ADD) || ++ (((asd & AD_SP_MASK) >> AD_SP_SHIFT) != sp) || ++ ((asd & AD_ST_MASK) != st)) { ++ /* This is not what we want, "push" it back */ ++ (*eromptr)--; ++ return 0; ++ } ++ *addrl = asd & AD_ADDR_MASK; ++ if (asd & AD_AG32) { ++ *addrh = get_erom_ent(sih, eromptr, 0, 0); ++ } else { ++ *addrh = 0; ++ } ++ *sizeh = 0; ++ sz = asd & AD_SZ_MASK; ++ if (sz == AD_SZ_SZD) { ++ szd = get_erom_ent(sih, eromptr, 0, 0); ++ *sizel = szd & SD_SZ_MASK; ++ if (szd & SD_SG32) { ++ *sizeh = get_erom_ent(sih, eromptr, 0, 0); ++ } ++ } else { ++ *sizel = AD_SZ_BASE << (sz >> AD_SZ_SHIFT); ++ } ++ ++ SI_VMSG((" SP %d, ad %d: st = %d, 0x%08x_0x%08x @ 0x%08x_0x%08x\n", ++ sp, ad, st, *sizeh, *sizel, *addrh, *addrl)); ++ ++ return asd; ++} ++ ++/* parse the enumeration rom to identify all cores */ ++void ++BCMATTACHFN(ai_scan)(si_t *sih, void *regs, uint devid) ++{ ++ si_info_t *sii = SI_INFO(sih); ++ chipcregs_t *cc = (chipcregs_t *)regs; ++ uint32 erombase, *eromptr, *eromlim; ++ ++ erombase = R_REG(sii->osh, &cc->eromptr); ++ ++ switch (BUSTYPE(sih->bustype)) { ++ case SI_BUS: ++#if defined(CONFIG_MACH_HX4) ++ eromptr = hx4_erom; ++#elif defined(CONFIG_MACH_HR2) ++ eromptr = hr2_erom; ++#elif defined(CONFIG_MACH_KT2) ++ eromptr = kt2_erom; ++#elif defined(CONFIG_MACH_GH) ++ eromptr = gh_erom; ++#elif defined(CONFIG_MACH_SB2) ++ eromptr = sb2_erom; ++#elif defined(CONFIG_MACH_HR3) ++ eromptr = hr3_erom; ++#elif defined(CONFIG_MACH_GH2) ++ eromptr = gh2_erom; ++#endif ++ break; ++ ++ case PCI_BUS: ++ /* Set wrappers address */ ++ sii->curwrap = (void *)((uintptr)regs + SI_CORE_SIZE); ++ ++ /* Now point the window at the erom */ ++ OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, erombase); ++ eromptr = regs; ++ break; ++ ++ case PCMCIA_BUS: ++ default: ++ SI_ERROR(("Don't know how to do AXI enumertion on bus %d\n", sih->bustype)); ++ ASSERT(0); ++ return; ++ } ++ eromlim = eromptr + (ER_REMAPCONTROL / sizeof(uint32)); ++ ++ SI_VMSG(("ai_scan: regs = 0x%p, erombase = 0x%08x, eromptr = 0x%p, eromlim = 0x%p\n", ++ regs, erombase, eromptr, eromlim)); ++ while (eromptr < eromlim) { ++ uint32 cia, cib, cid, mfg, crev, nmw, nsw, nmp, nsp; ++ uint32 mpd, asd, addrl, addrh, sizel, sizeh; ++ uint i, j, idx; ++ bool br; ++ ++ br = FALSE; ++ ++ /* Grok a component */ ++ cia = get_erom_ent(sih, &eromptr, ER_TAG, ER_CI); ++ if (cia == (ER_END | ER_VALID)) { ++ SI_VMSG(("Found END of erom after %d cores\n", sii->numcores)); ++ return; ++ } ++ ++ cib = get_erom_ent(sih, &eromptr, 0, 0); ++ ++ if ((cib & ER_TAG) != ER_CI) { ++ SI_ERROR(("CIA not followed by CIB\n")); ++ goto error; ++ } ++ ++ cid = (cia & CIA_CID_MASK) >> CIA_CID_SHIFT; ++ mfg = (cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT; ++ crev = (cib & CIB_REV_MASK) >> CIB_REV_SHIFT; ++ nmw = (cib & CIB_NMW_MASK) >> CIB_NMW_SHIFT; ++ nsw = (cib & CIB_NSW_MASK) >> CIB_NSW_SHIFT; ++ nmp = (cib & CIB_NMP_MASK) >> CIB_NMP_SHIFT; ++ nsp = (cib & CIB_NSP_MASK) >> CIB_NSP_SHIFT; ++ ++#ifdef BCMDBG_SI ++ SI_VMSG(("Found component 0x%04x/0x%04x rev %d at erom addr 0x%p, with nmw = %d, " ++ "nsw = %d, nmp = %d & nsp = %d\n", ++ mfg, cid, crev, eromptr - 1, nmw, nsw, nmp, nsp)); ++#else ++ BCM_REFERENCE(crev); ++#endif ++ ++ if (((mfg == MFGID_ARM) && (cid == DEF_AI_COMP)) || (nsp == 0)) { ++ continue; ++ } ++ ++ if ((nmw + nsw == 0)) { ++ /* A component which is not a core */ ++ /* XXX: Should record some info */ ++ if (cid == OOB_ROUTER_CORE_ID) { ++ asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, ++ &addrl, &addrh, &sizel, &sizeh); ++ if (asd != 0) { ++ sii->oob_router = addrl; ++ } ++ } ++ if (cid != GMAC_COMMON_4706_CORE_ID) { ++ continue; ++ } ++ } ++ ++ idx = sii->numcores; ++ ++ sii->cia[idx] = cia; ++ sii->cib[idx] = cib; ++ sii->coreid[idx] = cid; ++ ++ for (i = 0; i < nmp; i++) { ++ mpd = get_erom_ent(sih, &eromptr, ER_VALID, ER_VALID); ++ if ((mpd & ER_TAG) != ER_MP) { ++ SI_ERROR(("Not enough MP entries for component 0x%x\n", cid)); ++ goto error; ++ } ++ /* XXX: Record something? */ ++ SI_VMSG((" Master port %d, mp: %d id: %d\n", i, ++ (mpd & MPD_MP_MASK) >> MPD_MP_SHIFT, ++ (mpd & MPD_MUI_MASK) >> MPD_MUI_SHIFT)); ++ } ++ ++ /* First Slave Address Descriptor should be port 0: ++ * the main register space for the core ++ */ ++ asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, &addrl, &addrh, &sizel, &sizeh); ++ if (asd == 0) { ++ do { ++ /* Try again to see if it is a bridge */ ++ asd = get_asd(sih, &eromptr, 0, 0, AD_ST_BRIDGE, &addrl, &addrh, ++ &sizel, &sizeh); ++ if (asd != 0) { ++ br = TRUE; ++ } else { ++ if (br == TRUE) { ++ break; ++ } else if ((addrh != 0) || (sizeh != 0) || ++ (sizel != SI_CORE_SIZE)) { ++ /* XXX: Could we have sizel != 4KB? */ ++ SI_ERROR(("addrh = 0x%x\t sizeh = 0x%x\t size1 =" ++ "0x%x\n", addrh, sizeh, sizel)); ++ SI_ERROR(("First Slave ASD for" ++ "core 0x%04x malformed " ++ "(0x%08x)\n", cid, asd)); ++ goto error; ++ } ++ } ++ } while (1); ++ } ++ sii->coresba[idx] = addrl; ++ sii->coresba_size[idx] = sizel; ++ /* Get any more ASDs in port 0 */ ++ j = 1; ++ do { ++ asd = get_asd(sih, &eromptr, 0, j, AD_ST_SLAVE, &addrl, &addrh, ++ &sizel, &sizeh); ++ if ((asd != 0) && (j == 1) && (sizel == SI_CORE_SIZE)) { ++ sii->coresba2[idx] = addrl; ++ sii->coresba2_size[idx] = sizel; ++ } ++ j++; ++ } while (asd != 0); ++ ++ /* Go through the ASDs for other slave ports */ ++ for (i = 1; i < nsp; i++) { ++ j = 0; ++ do { ++ asd = get_asd(sih, &eromptr, i, j, AD_ST_SLAVE, &addrl, &addrh, ++ &sizel, &sizeh); ++ /* XXX: Should record them so we can do error recovery later */ ++ ++ if (asd == 0) ++ break; ++ j++; ++ } while (1); ++ if (j == 0) { ++ SI_ERROR((" SP %d has no address descriptors\n", i)); ++ goto error; ++ } ++ } ++ ++ /* Now get master wrappers */ ++ for (i = 0; i < nmw; i++) { ++ asd = get_asd(sih, &eromptr, i, 0, AD_ST_MWRAP, &addrl, &addrh, ++ &sizel, &sizeh); ++ if (asd == 0) { ++ SI_ERROR(("Missing descriptor for MW %d\n", i)); ++ goto error; ++ } ++ if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) { ++ SI_ERROR(("Master wrapper %d is not 4KB\n", i)); ++ goto error; ++ } ++ if (i == 0) { ++ sii->wrapba[idx] = addrl; ++ } ++ } ++ ++ /* And finally slave wrappers */ ++ for (i = 0; i < nsw; i++) { ++ uint fwp = (nsp == 1) ? 0 : 1; ++ asd = get_asd(sih, &eromptr, fwp + i, 0, AD_ST_SWRAP, &addrl, &addrh, ++ &sizel, &sizeh); ++ if (asd == 0) { ++ SI_ERROR(("Missing descriptor for SW %d\n", i)); ++ goto error; ++ } ++ if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) { ++ SI_ERROR(("Slave wrapper %d is not 4KB\n", i)); ++ goto error; ++ } ++ if ((nmw == 0) && (i == 0)) { ++ sii->wrapba[idx] = addrl; ++ } ++ } ++ ++ /* Don't record bridges */ ++ if (br) { ++ continue; ++ } ++ ++ /* Done with core */ ++ sii->numcores++; ++ } ++ ++ SI_ERROR(("Reached end of erom without finding END")); ++ ++error: ++ sii->numcores = 0; ++ return; ++} ++ ++/* This function changes the logical "focus" to the indicated core. ++ * Return the current core's virtual address. ++ */ ++void * ++ai_setcoreidx(si_t *sih, uint coreidx) ++{ ++ si_info_t *sii = SI_INFO(sih); ++ uint32 addr, wrap; ++ void *regs; ++ ++ if (coreidx >= MIN(sii->numcores, SI_MAXCORES)) { ++ return (NULL); ++ } ++ ++ addr = sii->coresba[coreidx]; ++ wrap = sii->wrapba[coreidx]; ++ ++ /* ++ * If the user has provided an interrupt mask enabled function, ++ * then assert interrupts are disabled before switching the core. ++ */ ++ ASSERT((sii->intrsenabled_fn == NULL) || !(*(sii)->intrsenabled_fn)((sii)->intr_arg)); ++ ++ switch (BUSTYPE(sih->bustype)) { ++ case SI_BUS: ++ /* map new one */ ++ if (!sii->regs[coreidx]) { ++ sii->regs[coreidx] = REG_MAP(addr, SI_CORE_SIZE); ++ ASSERT(GOODREGS(sii->regs[coreidx])); ++ } ++ sii->curmap = regs = sii->regs[coreidx]; ++ if (!sii->wrappers[coreidx]) { ++ sii->wrappers[coreidx] = REG_MAP(wrap, SI_CORE_SIZE); ++ ASSERT(GOODREGS(sii->wrappers[coreidx])); ++ } ++ sii->curwrap = sii->wrappers[coreidx]; ++ break; ++ ++ case PCI_BUS: ++ /* point bar0 window */ ++ OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, addr); ++ regs = sii->curmap; ++ /* point bar0 2nd 4KB window to the primary wrapper */ ++ if (PCIE_GEN2(sii)) { ++ OSL_PCI_WRITE_CONFIG(sii->osh, PCIE2_BAR0_WIN2, 4, wrap); ++ } else { ++ OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN2, 4, wrap); ++ } ++ break; ++ ++ case PCMCIA_BUS: ++ default: ++ ASSERT(0); ++ regs = NULL; ++ break; ++ } ++ ++ sii->curmap = regs; ++ sii->curidx = coreidx; ++ ++ return regs; ++} ++ ++void ++ai_coreaddrspaceX(si_t *sih, uint asidx, uint32 *addr, uint32 *size) ++{ ++ si_info_t *sii = SI_INFO(sih); ++ chipcregs_t *cc = NULL; ++ uint32 erombase, *eromptr, *eromlim; ++ uint i, j, cidx; ++ uint32 cia, cib, nmp, nsp; ++ uint32 asd, addrl, addrh, sizel, sizeh; ++ ++ for (i = 0; i < sii->numcores; i++) { ++ if (sii->coreid[i] == CC_CORE_ID) { ++ cc = (chipcregs_t *)sii->regs[i]; ++ break; ++ } ++ } ++ if (cc == NULL) { ++ goto error; ++ } ++ ++ erombase = R_REG(sii->osh, &cc->eromptr); ++ eromptr = (uint32 *)REG_MAP(erombase, SI_CORE_SIZE); ++ eromlim = eromptr + (ER_REMAPCONTROL / sizeof(uint32)); ++ ++ cidx = sii->curidx; ++ cia = sii->cia[cidx]; ++ cib = sii->cib[cidx]; ++ ++ nmp = (cib & CIB_NMP_MASK) >> CIB_NMP_SHIFT; ++ nsp = (cib & CIB_NSP_MASK) >> CIB_NSP_SHIFT; ++ ++ /* scan for cores */ ++ while (eromptr < eromlim) { ++ if ((get_erom_ent(sih, &eromptr, ER_TAG, ER_CI) == cia) && ++ (get_erom_ent(sih, &eromptr, 0, 0) == cib)) { ++ break; ++ } ++ } ++ ++ /* skip master ports */ ++ for (i = 0; i < nmp; i++) { ++ get_erom_ent(sih, &eromptr, ER_VALID, ER_VALID); ++ } ++ ++ /* Skip ASDs in port 0 */ ++ asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, &addrl, &addrh, &sizel, &sizeh); ++ if (asd == 0) { ++ /* Try again to see if it is a bridge */ ++ asd = get_asd(sih, &eromptr, 0, 0, AD_ST_BRIDGE, &addrl, &addrh, ++ &sizel, &sizeh); ++ } ++ ++ j = 1; ++ do { ++ asd = get_asd(sih, &eromptr, 0, j, AD_ST_SLAVE, &addrl, &addrh, ++ &sizel, &sizeh); ++ j++; ++ } while (asd != 0); ++ ++ /* Go through the ASDs for other slave ports */ ++ for (i = 1; i < nsp; i++) { ++ j = 0; ++ do { ++ asd = get_asd(sih, &eromptr, i, j, AD_ST_SLAVE, &addrl, &addrh, ++ &sizel, &sizeh); ++ if (asd == 0) { ++ break; ++ } ++ ++ if (!asidx--) { ++ *addr = addrl; ++ *size = sizel; ++ return; ++ } ++ j++; ++ } while (1); ++ ++ if (j == 0) { ++ SI_ERROR((" SP %d has no address descriptors\n", i)); ++ break; ++ } ++ } ++ ++error: ++ *size = 0; ++ return; ++} ++ ++/* Return the number of address spaces in current core */ ++int ++ai_numaddrspaces(si_t *sih) ++{ ++ /* XXX: Either save ot or parse the EROM on demand */ ++ return 2; ++} ++ ++/* Return the address of the nth address space in the current core */ ++uint32 ++ai_addrspace(si_t *sih, uint asidx) ++{ ++ si_info_t *sii; ++ uint cidx; ++ ++ sii = SI_INFO(sih); ++ cidx = sii->curidx; ++ ++ if (asidx == 0) { ++ return sii->coresba[cidx]; ++ } else if (asidx == 1) { ++ return sii->coresba2[cidx]; ++ } else { ++ SI_ERROR(("%s: Need to parse the erom again to find addr space %d\n", ++ __FUNCTION__, asidx)); ++ return 0; ++ } ++} ++ ++/* Return the size of the nth address space in the current core */ ++uint32 ++ai_addrspacesize(si_t *sih, uint asidx) ++{ ++ si_info_t *sii; ++ uint cidx; ++ ++ sii = SI_INFO(sih); ++ cidx = sii->curidx; ++ ++ if (asidx == 0) { ++ return sii->coresba_size[cidx]; ++ } else if (asidx == 1) { ++ return sii->coresba2_size[cidx]; ++ } else { ++ SI_ERROR(("%s: Need to parse the erom again to find addr space %d\n", ++ __FUNCTION__, asidx)); ++ return 0; ++ } ++} ++ ++uint ++ai_flag(si_t *sih) ++{ ++ si_info_t *sii; ++ aidmp_t *ai; ++ ++ sii = SI_INFO(sih); ++ ai = sii->curwrap; ++ return (R_REG(sii->osh, &ai->oobselouta30) & 0x1f); ++} ++ ++void ++ai_setint(si_t *sih, int siflag) ++{ ++ /* XXX: Figure out OOB stuff */ ++} ++ ++uint ++ai_wrap_reg(si_t *sih, uint32 offset, uint32 mask, uint32 val) ++{ ++ si_info_t *sii = SI_INFO(sih); ++ uint32 *map = (uint32 *) sii->curwrap; ++ ++ if (mask || val) { ++ uint32 w = R_REG(sii->osh, map+(offset/4)); ++ w &= ~mask; ++ w |= val; ++ W_REG(sii->osh, map+(offset/4), val); ++ } ++ ++ return (R_REG(sii->osh, map+(offset/4))); ++} ++ ++uint ++ai_corevendor(si_t *sih) ++{ ++ si_info_t *sii; ++ uint32 cia; ++ ++ sii = SI_INFO(sih); ++ cia = sii->cia[sii->curidx]; ++ return ((cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT); ++} ++ ++uint ++ai_corerev(si_t *sih) ++{ ++ si_info_t *sii; ++ uint32 cib; ++ ++ sii = SI_INFO(sih); ++ cib = sii->cib[sii->curidx]; ++ return ((cib & CIB_REV_MASK) >> CIB_REV_SHIFT); ++} ++ ++bool ++ai_iscoreup(si_t *sih) ++{ ++ si_info_t *sii; ++ aidmp_t *ai; ++ ++ sii = SI_INFO(sih); ++ ai = sii->curwrap; ++ ++ return (((R_REG(sii->osh, &ai->ioctrl) & (SICF_FGC | SICF_CLOCK_EN)) == SICF_CLOCK_EN) && ++ ((R_REG(sii->osh, &ai->resetctrl) & AIRC_RESET) == 0)); ++} ++ ++/* ++ * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set operation, ++ * switch back to the original core, and return the new value. ++ * ++ * When using the silicon backplane, no fiddling with interrupts or core switches is needed. ++ * ++ * Also, when using pci/pcie, we can optimize away the core switching for pci registers ++ * and (on newer pci cores) chipcommon registers. ++ */ ++uint ++ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) ++{ ++ uint origidx = 0; ++ uint32 *r = NULL; ++ uint w; ++ uint intr_val = 0; ++ bool fast = FALSE; ++ si_info_t *sii; ++ ++ sii = SI_INFO(sih); ++ ++ ASSERT(GOODIDX(coreidx)); ++ ASSERT(regoff < SI_CORE_SIZE); ++ ASSERT((val & ~mask) == 0); ++ ++ if (coreidx >= SI_MAXCORES) { ++ return 0; ++ } ++ ++ if (BUSTYPE(sih->bustype) == SI_BUS) { ++ /* If internal bus, we can always get at everything */ ++ fast = TRUE; ++ /* map if does not exist */ ++ if (!sii->regs[coreidx]) { ++ sii->regs[coreidx] = REG_MAP(sii->coresba[coreidx], ++ SI_CORE_SIZE); ++ ASSERT(GOODREGS(sii->regs[coreidx])); ++ } ++ r = (uint32 *)((uchar *)sii->regs[coreidx] + regoff); ++ } else if (BUSTYPE(sih->bustype) == PCI_BUS) { ++ /* If pci/pcie, we can get at pci/pcie regs and on newer cores to chipc */ ++ ++ if ((sii->coreid[coreidx] == CC_CORE_ID) && SI_FAST(sii)) { ++ /* Chipc registers are mapped at 12KB */ ++ ++ fast = TRUE; ++ r = (uint32 *)((char *)sii->curmap + PCI_16KB0_CCREGS_OFFSET + regoff); ++ } else if (sii->pub.buscoreidx == coreidx) { ++ /* pci registers are at either in the last 2KB of an 8KB window ++ * or, in pcie and pci rev 13 at 8KB ++ */ ++ fast = TRUE; ++ if (SI_FAST(sii)) { ++ r = (uint32 *)((char *)sii->curmap + ++ PCI_16KB0_PCIREGS_OFFSET + regoff); ++ } else { ++ r = (uint32 *)((char *)sii->curmap + ++ ((regoff >= SBCONFIGOFF) ? ++ PCI_BAR0_PCISBR_OFFSET : PCI_BAR0_PCIREGS_OFFSET) + ++ regoff); ++ } ++ } ++ } ++ ++ if (!fast) { ++ INTR_OFF(sii, intr_val); ++ ++ /* save current core index */ ++ origidx = si_coreidx(&sii->pub); ++ ++ /* switch core */ ++ r = (uint32*) ((uchar*) ai_setcoreidx(&sii->pub, coreidx) + regoff); ++ } ++ ASSERT(r != NULL); ++ ++ /* mask and set */ ++ if (mask || val) { ++ w = (R_REG(sii->osh, r) & ~mask) | val; ++ W_REG(sii->osh, r, w); ++ } ++ ++ /* readback */ ++ w = R_REG(sii->osh, r); ++ ++ if (!fast) { ++ /* restore core index */ ++ if (origidx != coreidx) { ++ ai_setcoreidx(&sii->pub, origidx); ++ } ++ ++ INTR_RESTORE(sii, intr_val); ++ } ++ ++ return (w); ++} ++ ++void ++ai_core_disable(si_t *sih, uint32 bits) ++{ ++ si_info_t *sii; ++ volatile uint32 dummy; ++ uint32 status; ++ aidmp_t *ai; ++ ++ sii = SI_INFO(sih); ++ ++ ASSERT(GOODREGS(sii->curwrap)); ++ ai = sii->curwrap; ++ ++ /* if core is already in reset, just return */ ++ if (R_REG(sii->osh, &ai->resetctrl) & AIRC_RESET) { ++ return; ++ } ++ ++ /* ensure there are no pending backplane operations */ ++ SPINWAIT(((status = R_REG(sii->osh, &ai->resetstatus)) != 0), 300); ++ ++ /* if pending backplane ops still, try waiting longer */ ++ if (status != 0) { ++ /* 300usecs was sufficient to allow backplane ops to clear for big hammer */ ++ /* during driver load we may need more time */ ++ SPINWAIT(((status = R_REG(sii->osh, &ai->resetstatus)) != 0), 10000); ++ /* if still pending ops, continue on and try disable anyway */ ++ /* this is in big hammer path, so don't call wl_reinit in this case... */ ++#ifdef BCMDBG ++ if (status != 0) { ++ printf("%s: WARN: resetstatus=%0x on core disable\n", __FUNCTION__, status); ++ } ++#endif ++ } ++ ++ W_REG(sii->osh, &ai->ioctrl, bits); ++ dummy = R_REG(sii->osh, &ai->ioctrl); ++ BCM_REFERENCE(dummy); ++ OSL_DELAY(10); ++ ++ W_REG(sii->osh, &ai->resetctrl, AIRC_RESET); ++ dummy = R_REG(sii->osh, &ai->resetctrl); ++ BCM_REFERENCE(dummy); ++ OSL_DELAY(1); ++} ++ ++/* reset and re-enable a core ++ * inputs: ++ * bits - core specific bits that are set during and after reset sequence ++ * resetbits - core specific bits that are set only during reset sequence ++ */ ++void ++ai_core_reset(si_t *sih, uint32 bits, uint32 resetbits) ++{ ++ si_info_t *sii; ++ aidmp_t *ai; ++ volatile uint32 dummy; ++ ++ sii = SI_INFO(sih); ++ ASSERT(GOODREGS(sii->curwrap)); ++ ai = sii->curwrap; ++ ++#ifdef CONFIG_BCM_IPROC_GMAC_ACP ++ bits = resetbits = R_REG(sii->osh, &ai->ioctrl) & 0xFFFFFFFC; ++#endif /* CONFIG_BCM_IPROC_GMAC_ACP */ ++ ++ /* ++ * Must do the disable sequence first to work for arbitrary current core state. ++ */ ++ ai_core_disable(sih, (bits | resetbits)); ++ ++ /* ++ * Now do the initialization sequence. ++ */ ++ W_REG(sii->osh, &ai->ioctrl, (bits | SICF_FGC | SICF_CLOCK_EN)); ++ dummy = R_REG(sii->osh, &ai->ioctrl); ++ BCM_REFERENCE(dummy); ++ ++ W_REG(sii->osh, &ai->resetctrl, 0); ++ dummy = R_REG(sii->osh, &ai->resetctrl); ++ BCM_REFERENCE(dummy); ++ OSL_DELAY(1); ++ ++ W_REG(sii->osh, &ai->ioctrl, (bits | SICF_CLOCK_EN)); ++ dummy = R_REG(sii->osh, &ai->ioctrl); ++ BCM_REFERENCE(dummy); ++ OSL_DELAY(1); ++} ++ ++void ++ai_core_cflags_wo(si_t *sih, uint32 mask, uint32 val) ++{ ++ si_info_t *sii; ++ aidmp_t *ai; ++ uint32 w; ++ ++ sii = SI_INFO(sih); ++ ++ ASSERT(GOODREGS(sii->curwrap)); ++ ai = sii->curwrap; ++ ++ ASSERT((val & ~mask) == 0); ++ ++ if (mask || val) { ++ w = ((R_REG(sii->osh, &ai->ioctrl) & ~mask) | val); ++ W_REG(sii->osh, &ai->ioctrl, w); ++ } ++} ++ ++uint32 ++ai_core_cflags(si_t *sih, uint32 mask, uint32 val) ++{ ++ si_info_t *sii; ++ aidmp_t *ai; ++ uint32 w; ++ ++ sii = SI_INFO(sih); ++ ++ ASSERT(GOODREGS(sii->curwrap)); ++ ai = sii->curwrap; ++ ++ ASSERT((val & ~mask) == 0); ++ ++ if (mask || val) { ++ w = ((R_REG(sii->osh, &ai->ioctrl) & ~mask) | val); ++ W_REG(sii->osh, &ai->ioctrl, w); ++ } ++ ++ return R_REG(sii->osh, &ai->ioctrl); ++} ++ ++uint32 ++ai_core_sflags(si_t *sih, uint32 mask, uint32 val) ++{ ++ si_info_t *sii; ++ aidmp_t *ai; ++ uint32 w; ++ ++ sii = SI_INFO(sih); ++ ++ ASSERT(GOODREGS(sii->curwrap)); ++ ai = sii->curwrap; ++ ++ ASSERT((val & ~mask) == 0); ++ ASSERT((mask & ~SISF_CORE_BITS) == 0); ++ ++ if (mask || val) { ++ w = ((R_REG(sii->osh, &ai->iostatus) & ~mask) | val); ++ W_REG(sii->osh, &ai->iostatus, w); ++ } ++ ++ return R_REG(sii->osh, &ai->iostatus); ++} ++ ++#if defined(BCMDBG) || defined(BCMDBG_DUMP) ++/* print interesting aidmp registers */ ++void ++ai_dumpregs(si_t *sih, struct bcmstrbuf *b) ++{ ++ si_info_t *sii; ++ osl_t *osh; ++ aidmp_t *ai; ++ uint i; ++ ++ sii = SI_INFO(sih); ++ osh = sii->osh; ++ ++ for (i = 0; i < sii->numcores; i++) { ++ si_setcoreidx(&sii->pub, i); ++ ai = sii->curwrap; ++ ++ bcm_bprintf(b, "core 0x%x: \n", sii->coreid[i]); ++ bcm_bprintf(b, "ioctrlset 0x%x ioctrlclear 0x%x ioctrl 0x%x iostatus 0x%x" ++ "ioctrlwidth 0x%x iostatuswidth 0x%x\n" ++ "resetctrl 0x%x resetstatus 0x%x resetreadid 0x%x resetwriteid 0x%x\n" ++ "errlogctrl 0x%x errlogdone 0x%x errlogstatus 0x%x" ++ "errlogaddrlo 0x%x errlogaddrhi 0x%x\n" ++ "errlogid 0x%x errloguser 0x%x errlogflags 0x%x\n" ++ "intstatus 0x%x config 0x%x itcr 0x%x\n", ++ R_REG(osh, &ai->ioctrlset), ++ R_REG(osh, &ai->ioctrlclear), ++ R_REG(osh, &ai->ioctrl), ++ R_REG(osh, &ai->iostatus), ++ R_REG(osh, &ai->ioctrlwidth), ++ R_REG(osh, &ai->iostatuswidth), ++ R_REG(osh, &ai->resetctrl), ++ R_REG(osh, &ai->resetstatus), ++ R_REG(osh, &ai->resetreadid), ++ R_REG(osh, &ai->resetwriteid), ++ R_REG(osh, &ai->errlogctrl), ++ R_REG(osh, &ai->errlogdone), ++ R_REG(osh, &ai->errlogstatus), ++ R_REG(osh, &ai->errlogaddrlo), ++ R_REG(osh, &ai->errlogaddrhi), ++ R_REG(osh, &ai->errlogid), ++ R_REG(osh, &ai->errloguser), ++ R_REG(osh, &ai->errlogflags), ++ R_REG(osh, &ai->intstatus), ++ R_REG(osh, &ai->config), ++ R_REG(osh, &ai->itcr)); ++ } ++} ++#endif /* BCMDBG || BCMDBG_DUMP */ ++ ++#ifdef BCMDBG ++static void ++_ai_view(osl_t *osh, aidmp_t *ai, uint32 cid, uint32 addr, bool verbose) ++{ ++ uint32 config; ++ ++ config = R_REG(osh, &ai->config); ++ SI_ERROR(("\nCore ID: 0x%x, addr 0x%x, config 0x%x\n", cid, addr, config)); ++ ++ if (config & AICFG_RST) { ++ SI_ERROR(("resetctrl 0x%x, resetstatus 0x%x, resetreadid 0x%x, resetwriteid 0x%x\n", ++ R_REG(osh, &ai->resetctrl), R_REG(osh, &ai->resetstatus), ++ R_REG(osh, &ai->resetreadid), R_REG(osh, &ai->resetwriteid))); ++ } ++ ++ if (config & AICFG_IOC) { ++ SI_ERROR(("ioctrl 0x%x, width %d\n", R_REG(osh, &ai->ioctrl), ++ R_REG(osh, &ai->ioctrlwidth))); ++ } ++ ++ if (config & AICFG_IOS) { ++ SI_ERROR(("iostatus 0x%x, width %d\n", R_REG(osh, &ai->iostatus), ++ R_REG(osh, &ai->iostatuswidth))); ++ } ++ ++ if (config & AICFG_ERRL) { ++ SI_ERROR(("errlogctrl 0x%x, errlogdone 0x%x, errlogstatus 0x%x, intstatus 0x%x\n", ++ R_REG(osh, &ai->errlogctrl), R_REG(osh, &ai->errlogdone), ++ R_REG(osh, &ai->errlogstatus), R_REG(osh, &ai->intstatus))); ++ SI_ERROR(("errlogid 0x%x, errloguser 0x%x, errlogflags 0x%x, errlogaddr " ++ "0x%x/0x%x\n", ++ R_REG(osh, &ai->errlogid), R_REG(osh, &ai->errloguser), ++ R_REG(osh, &ai->errlogflags), R_REG(osh, &ai->errlogaddrhi), ++ R_REG(osh, &ai->errlogaddrlo))); ++ } ++ ++ if (verbose && (config & AICFG_OOB)) { ++ SI_ERROR(("oobselina30 0x%x, oobselina74 0x%x\n", ++ R_REG(osh, &ai->oobselina30), R_REG(osh, &ai->oobselina74))); ++ SI_ERROR(("oobselinb30 0x%x, oobselinb74 0x%x\n", ++ R_REG(osh, &ai->oobselinb30), R_REG(osh, &ai->oobselinb74))); ++ SI_ERROR(("oobselinc30 0x%x, oobselinc74 0x%x\n", ++ R_REG(osh, &ai->oobselinc30), R_REG(osh, &ai->oobselinc74))); ++ SI_ERROR(("oobselind30 0x%x, oobselind74 0x%x\n", ++ R_REG(osh, &ai->oobselind30), R_REG(osh, &ai->oobselind74))); ++ SI_ERROR(("oobselouta30 0x%x, oobselouta74 0x%x\n", ++ R_REG(osh, &ai->oobselouta30), R_REG(osh, &ai->oobselouta74))); ++ SI_ERROR(("oobseloutb30 0x%x, oobseloutb74 0x%x\n", ++ R_REG(osh, &ai->oobseloutb30), R_REG(osh, &ai->oobseloutb74))); ++ SI_ERROR(("oobseloutc30 0x%x, oobseloutc74 0x%x\n", ++ R_REG(osh, &ai->oobseloutc30), R_REG(osh, &ai->oobseloutc74))); ++ SI_ERROR(("oobseloutd30 0x%x, oobseloutd74 0x%x\n", ++ R_REG(osh, &ai->oobseloutd30), R_REG(osh, &ai->oobseloutd74))); ++ SI_ERROR(("oobsynca 0x%x, oobseloutaen 0x%x\n", ++ R_REG(osh, &ai->oobsynca), R_REG(osh, &ai->oobseloutaen))); ++ SI_ERROR(("oobsyncb 0x%x, oobseloutben 0x%x\n", ++ R_REG(osh, &ai->oobsyncb), R_REG(osh, &ai->oobseloutben))); ++ SI_ERROR(("oobsyncc 0x%x, oobseloutcen 0x%x\n", ++ R_REG(osh, &ai->oobsyncc), R_REG(osh, &ai->oobseloutcen))); ++ SI_ERROR(("oobsyncd 0x%x, oobseloutden 0x%x\n", ++ R_REG(osh, &ai->oobsyncd), R_REG(osh, &ai->oobseloutden))); ++ SI_ERROR(("oobaextwidth 0x%x, oobainwidth 0x%x, oobaoutwidth 0x%x\n", ++ R_REG(osh, &ai->oobaextwidth), R_REG(osh, &ai->oobainwidth), ++ R_REG(osh, &ai->oobaoutwidth))); ++ SI_ERROR(("oobbextwidth 0x%x, oobbinwidth 0x%x, oobboutwidth 0x%x\n", ++ R_REG(osh, &ai->oobbextwidth), R_REG(osh, &ai->oobbinwidth), ++ R_REG(osh, &ai->oobboutwidth))); ++ SI_ERROR(("oobcextwidth 0x%x, oobcinwidth 0x%x, oobcoutwidth 0x%x\n", ++ R_REG(osh, &ai->oobcextwidth), R_REG(osh, &ai->oobcinwidth), ++ R_REG(osh, &ai->oobcoutwidth))); ++ SI_ERROR(("oobdextwidth 0x%x, oobdinwidth 0x%x, oobdoutwidth 0x%x\n", ++ R_REG(osh, &ai->oobdextwidth), R_REG(osh, &ai->oobdinwidth), ++ R_REG(osh, &ai->oobdoutwidth))); ++ } ++} ++ ++void ++ai_view(si_t *sih, bool verbose) ++{ ++ si_info_t *sii; ++ osl_t *osh; ++ aidmp_t *ai; ++ uint32 cid, addr; ++ ++ sii = SI_INFO(sih); ++ ai = sii->curwrap; ++ osh = sii->osh; ++ ++ cid = sii->coreid[sii->curidx]; ++ addr = sii->wrapba[sii->curidx]; ++ _ai_view(osh, ai, cid, addr, verbose); ++} ++ ++void ++ai_viewall(si_t *sih, bool verbose) ++{ ++ si_info_t *sii; ++ osl_t *osh; ++ aidmp_t *ai; ++ uint32 cid, addr; ++ uint i; ++ ++ sii = SI_INFO(sih); ++ osh = sii->osh; ++ for (i = 0; i < sii->numcores; i++) { ++ si_setcoreidx(sih, i); ++ ++ ai = sii->curwrap; ++ cid = sii->coreid[sii->curidx]; ++ addr = sii->wrapba[sii->curidx]; ++ _ai_view(osh, ai, cid, addr, verbose); ++ } ++} ++#endif /* BCMDBG */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_egphy28.c b/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_egphy28.c +--- a/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_egphy28.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_egphy28.c 2017-11-09 17:53:44.024296000 +0800 +@@ -0,0 +1,352 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ * ++ * These routines provide access to the external phy ++ * ++ */ ++#include ++#include ++#include "../../../mdio/iproc_mdio.h" ++#include "bcmiproc_phy.h" ++#include "bcmiproc_egphy28.h" ++ ++/* debug/trace */ ++//#define BCMDBG ++//#define BCMDBG_ERR ++#ifdef BCMDBG ++#define NET_ERROR(args) printf args ++#define NET_TRACE(args) printf args ++#elif defined(BCMDBG_ERR) ++#define NET_ERROR(args) printf args ++#define NET_TRACE(args) ++#else ++#define NET_ERROR(args) ++#define NET_TRACE(args) ++#endif /* BCMDBG */ ++#define NET_REG_TRACE(args) ++ ++extern u32 cmicd_schan_write(void __iomem *base, u32 ctrl, u32 addr, u32 val); ++extern u32 cmicd_schan_read(void __iomem *base, u32 ctrl, u32 addr); ++ ++ ++static int ++egphy28_rdb_reg_read(u32 phy_addr, u32 reg_addr, u16 *data) ++{ ++ int rv = SOC_E_NONE; ++ ++ /* MDIO write the RDB reg. address to reg.0x1E = */ ++ iproc_mii_write(MII_DEV_LOCAL, phy_addr, EGPHY28_REG_RDB_ADDR, ++ (0xffff & reg_addr)); ++ ++ /* MDIO read from reg.0x1F to get the RDB register's value as */ ++ iproc_mii_read(MII_DEV_LOCAL, phy_addr, EGPHY28_REG_RDB_DATA, data); ++ ++ return rv; ++} ++ ++static int ++egphy28_rdb_reg_write(u32 phy_addr, u32 reg_addr, u16 data) ++{ ++ int rv = SOC_E_NONE; ++ ++ /* MDIO write the RDB reg. address to reg.0x1E = */ ++ iproc_mii_write(MII_DEV_LOCAL, phy_addr, EGPHY28_REG_RDB_ADDR, ++ (0xffff & reg_addr)); ++ ++ /* MDIO write to reg.0x1F to set the RDB resister's value as */ ++ iproc_mii_write(MII_DEV_LOCAL, phy_addr, EGPHY28_REG_RDB_DATA, data); ++ ++ return rv; ++} ++ ++static void ++egphy28_rdb_reg_modify(u32 phy_addr, int reg_addr, u16 data, u16 mask) ++{ ++ u16 ori_data; ++ ++ egphy28_rdb_reg_read(phy_addr, reg_addr, &ori_data); ++ ori_data &= ~mask; ++ ori_data |= (data & mask); ++ egphy28_rdb_reg_write(phy_addr, reg_addr, ori_data); ++} ++ ++int ++egphy28_reg_read(u32 phy_addr, int reg_addr, u16 *data) ++{ ++ int rv = SOC_E_NONE; ++ iproc_mii_read(MII_DEV_LOCAL, phy_addr, reg_addr, data); ++ ++ return rv; ++} ++ ++int ++egphy28_reg_write(u32 phy_addr, int reg_addr, u16 data) ++{ ++ int rv = SOC_E_NONE; ++ iproc_mii_write(MII_DEV_LOCAL, phy_addr, reg_addr, data); ++ ++ return rv; ++} ++ ++static void ++egphy28_reg_modify(u32 phy_addr, int reg_addr, u16 data, u16 mask) ++{ ++ u16 ori_data; ++ ++ egphy28_reg_read(phy_addr, reg_addr, &ori_data); ++ ori_data &= ~mask; ++ ori_data |= (data & mask); ++ egphy28_reg_write(phy_addr, reg_addr, ori_data); ++} ++ ++static int ++egphy28_ge_reset(u32 phy_addr) ++{ ++ int rv = SOC_E_NONE; ++ u16 val; ++ ++ NET_TRACE(("%s: phy_addr %d\n", __FUNCTION__, phy_addr)); ++ ++ /* Reset the PHY */ ++ egphy28_reg_read(phy_addr, EGPHY28_COPPER_MII_CTRL, &val); ++ val |= BMCR_RESET; ++ egphy28_reg_write(phy_addr, EGPHY28_COPPER_MII_CTRL, val); ++ ++ SPINWAIT((!egphy28_reg_read(phy_addr, EGPHY28_COPPER_MII_CTRL, &val) && ++ (val & BMCR_RESET)), 100000); ++ ++ /* Check if out of reset */ ++ egphy28_reg_read(phy_addr, EGPHY28_COPPER_MII_CTRL, &val); ++ if (val & BMCR_RESET) { ++ NET_ERROR(("%s reset not complete\n", __FUNCTION__)); ++ rv = SOC_E_TIMEOUT; ++ } else { ++ NET_TRACE(("%s reset complete\n", __FUNCTION__)); ++ } ++ ++ return rv; ++} ++ ++ ++#if 0 ++static void ++cmid_schan_modify(void __iomem *base, u32 ctrl, u32 addr, u32 val, u32 mask) ++{ ++ u32 ori_val; ++ ++ ori_val = cmicd_schan_read(base, ctrl, addr); ++ ori_val &= ~mask; ++ ori_val |= (val & mask); ++ cmicd_schan_write(base, ctrl, addr, ori_val); ++} ++#endif ++ ++ ++static int ++egphy28_ge_init(void __iomem *base, u32 phy_addr) ++{ ++ int rv = SOC_E_NONE; ++ /* ==== Power up PHY ==== */ ++#if 0 ++ /* Give initial value */ ++ /* TOP_QGPHY_CTRL_0.EXT_PWRDOWN[23:20] = LOW */ ++ cmid_schan_modify(base, 0x2c800200, 0x02033800, 0x0, 0x00F00000); ++ /* TOP_QGPHY_CTRL_2.GPHY_IDDQ_GLOBAL_PWR[18] = HIGH */ ++ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x40000, 0x040000); ++ /* TOP_QGPHY_CTRL_2.IDDQ_BIAS[5] = LOW */ ++ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x0, 0x20); ++ /* TOP_SOFT_RESET_REG.TOP_QGPHY_RST_L[21] = LOW */ ++ cmid_schan_modify(base, 0x2c800200, 0x02030400, 0x0, 0x200000); ++ ++ /* TOP_QGPHY_CTRL_2.GPHY_IDDQ_GLOBAL_PWR[18] = LOW */ ++ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x0, 0x040000); ++ /* TOP_SOFT_RESET_REG.TOP_QGPHY_RST_L[21] = HIGH */ ++ cmid_schan_modify(base, 0x2c800200, 0x02030400, 0x200000, 0x200000); ++ ++ /* ==== Partial Power down other 3 PHYs ==== */ ++ ++ /* Give initial value */ ++ /* TOP_QGPHY_CTRL_0.EXT_PWRDOWN[22:20] = LOW */ ++ cmid_schan_modify(base, 0x2c800200, 0x02033800, 0x0, 0x00700000); ++ /* TOP_QGPHY_CTRL_2.GPHY_IDDQ_GLOBAL_PWR[18] = HIGH */ ++ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x40000, 0x040000); ++ /* TOP_QGPHY_CTRL_2.IDDQ_BIAS[5] = LOW */ ++ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x0, 0x20); ++ /* TOP_SOFT_RESET_REG.TOP_QGPHY_RST_L[21] = LOW */ ++ cmid_schan_modify(base, 0x2c800200, 0x02030400, 0x0, 0x200000); ++ ++ /* TOP_QGPHY_CTRL_0.EXT_PWRDOWN[22:20] = HIGH */ ++ cmid_schan_modify(base, 0x2c800200, 0x02033800, 0x00700000, 0x00700000); ++ /* TOP_QGPHY_CTRL_2.IDDQ_BIAS[5] = HIGH */ ++ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x20, 0x20); ++ /* TOP_SOFT_RESET_REG.TOP_QGPHY_RST_L[21] = HIGH */ ++ cmid_schan_modify(base, 0x2c800200, 0x02030400, 0x200000, 0x200000); ++ ++ /* TOP_QGPHY_CTRL_2.GPHY_IDDQ_GLOBAL_PWR[18] = LOW */ ++ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x0, 0x040000); ++ /* TOP_QGPHY_CTRL_2.IDDQ_BIAS[5] = LOW */ ++ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x0, 0x20); ++ /* TOP_SOFT_RESET_REG.TOP_QGPHY_RST_L[21] = LOW */ ++ cmid_schan_modify(base, 0x2c800200, 0x02030400, 0x0, 0x200000); ++ ++ /* TOP_QGPHY_CTRL_2.GPHY_IDDQ_GLOBAL_PWR[18] = HIGH */ ++ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x040000, 0x040000); ++ /* TOP_QGPHY_CTRL_2.IDDQ_BIAS[5] = HIGH */ ++ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x20, 0x20); ++ /* TOP_SOFT_RESET_REG.TOP_QGPHY_RST_L[21] = HIGH */ ++ cmid_schan_modify(base, 0x2c800200, 0x02030400, 0x200000, 0x200000); ++ ++ /* TOP_QGPHY_CTRL_0.EXT_PWRDOWN[23] = LOW */ ++ cmid_schan_modify(base, 0x2c800200, 0x02033800, 0x0, 0x00800000); ++ /* TOP_QGPHY_CTRL_2.GPHY_IDDQ_GLOBAL_PWR[18] = LOW */ ++ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x0, 0x040000); ++ /* TOP_QGPHY_CTRL_2.IDDQ_BIAS[5] = LOW */ ++ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x0, 0x20); ++ /* TOP_SOFT_RESET_REG.TOP_QGPHY_RST_L[21] = LOW */ ++ cmid_schan_modify(base, 0x2c800200, 0x02030400, 0x0, 0x200000); ++ ++ /* TOP_SOFT_RESET_REG.TOP_QGPHY_RST_L[21] = HIGH */ ++ cmid_schan_modify(base, 0x2c800200, 0x02030400, 0x200000, 0x200000); ++ ++ /* Reset the PHY (Register[0x00], bit 15 = 1) */ ++ egphy28_reg_modify(phy_addr, EGPHY28_COPPER_MII_CTRL, BMCR_RESET, BMCR_RESET); ++ ++ /* ++ * Enable direct RDB addressing mode, write to Expansion register ++ * 0x7E = 0x0000 ++ * - MDIO write to reg 0x17 = 0x0F7E ++ * - MDIO write to reg 0x15 = 0x0000 ++ */ ++ egphy28_reg_write(phy_addr, EGPHY28_RDB_ACCESS_ADDR_1, EGPHY28_RDB_ACCESS_DATA_1); ++ egphy28_reg_write(phy_addr, EGPHY28_RDB_ACCESS_ADDR_2, EGPHY28_RDB_ACCESS_DATA_2); ++ ++ /* Clear Reset the PHY (Register[0x00], bit 15 = 0) */ ++ egphy28_reg_modify(phy_addr, EGPHY28_COPPER_MII_CTRL, 0x0, BMCR_RESET); ++ ++ /* Set MAC PHY interface to be GMII mode */ ++ egphy28_reg_modify(phy_addr, EGPGY28_MII_ECONTROL, 0x0, (1 << 15)); ++ ++ /* Set 1000BASE-T full-duplex and switch device port (Register[0x09], bit 9,10 = 1) */ ++ egphy28_reg_write(phy_addr, EGPHY28_MII_CTRL1000, ADVERTISE_1000FULL | REPEATER_DTE); ++ ++ /* Set Full-duplex, 1000BASE-T, Auto-Negoatiation, Restartr-AN ++ * (Register[0x00], bit 8, 6, 12, 9 = 1) ++ */ ++ egphy28_reg_write(phy_addr, EGPHY28_COPPER_MII_CTRL, (BMCR_FULLDPLX | BMCR_SPEED1000 | ++ BMCR_ANENABLE | BMCR_ANRESTART)); ++ ++ /* Disable super-isolate (RDB Register[0x02a], bit 5 = 0). in default */ ++ egphy28_rdb_reg_modify(phy_addr, 0x2a, 0x0, (1 << 5)); ++ ++ /* Remove power down (Register[0x00], bit 11 = 0). in default */ ++ egphy28_reg_modify(phy_addr, EGPHY28_COPPER_MII_CTRL, ~BMCR_PDOWN, BMCR_PDOWN); ++ ++ /* Enable LEDs to indicate traffic status (Register[0x10], bit 5 = 1) */ ++ egphy28_reg_modify(phy_addr, 0x10, (1 << 5), (1 << 5)); ++ ++ /* Enable extended packet length (4.5k through 25k) (RDB Register[0x28], bit 14 = 1) */ ++ egphy28_rdb_reg_modify(phy_addr, 0x28, (1 << 14), (1 << 14)); ++ ++ egphy28_rdb_reg_modify(phy_addr, 0x16, (1 << 0), (1 << 0)); ++ egphy28_rdb_reg_modify(phy_addr, 0x1b, (1 << 1), (1 << 1)); ++ ++ /* Configure LED selectors */ ++ /* Disable carrier extension */ ++ /* IEEE compliance setup */ ++ egphy28_rdb_reg_write(phy_addr, 0x1E4, 0x00C0); ++ egphy28_rdb_reg_write(phy_addr, 0x1E7, 0xB008); ++ egphy28_rdb_reg_write(phy_addr, 0x1E2, 0x02E3); ++ egphy28_rdb_reg_write(phy_addr, 0x1E0, 0x0D11); ++ egphy28_rdb_reg_write(phy_addr, 0x1E3, 0x7FC0); ++ egphy28_rdb_reg_write(phy_addr, 0x1EB, 0x6B40); ++ egphy28_rdb_reg_write(phy_addr, 0x1E8, 0x0213); ++ egphy28_rdb_reg_write(phy_addr, 0x1E9, 0x0020); ++ egphy28_rdb_reg_write(phy_addr, 0x28, 0x4C30); ++ egphy28_rdb_reg_write(phy_addr, 0x125, 0x211B); ++ egphy28_rdb_reg_write(phy_addr, 0xE, 0x0013); ++ egphy28_rdb_reg_write(phy_addr, 0xB0, 0x000C); ++ egphy28_rdb_reg_write(phy_addr, 0xB0, 0x0000); ++ ++ /* Set Full-duplex, 1000BASE-T, Auto-Negoatiation, Restartr-AN ++ * (Register[0x00], bit 8, 6, 12, 9 = 1) ++ */ ++ egphy28_reg_write(phy_addr, EGPHY28_COPPER_MII_CTRL, (BMCR_FULLDPLX | BMCR_SPEED1000 | ++ BMCR_ANENABLE | BMCR_ANRESTART)); ++ ++ /* Automatic Master/Slave configuration (Register[0x09], bit 12 = 0) in default */ ++ egphy28_reg_modify(phy_addr, EGPHY28_MII_CTRL1000, 0x0, (1 << 12)); ++ ++ /* Ability advert set : IEEE 802.3, 10HD, 100HD, 10FD, 100FD */ ++ /* (Register[0x04] bit 0, 5, 7, 6, 8 = 1 */ ++ egphy28_reg_modify(phy_addr, EGPHY28_MII_ADVERTISE, ++ (ADVERTISE_10HALF | ADVERTISE_100HALF | ADVERTISE_10FULL | ADVERTISE_100FULL | ADVERTISE_CSMA), ++ (ADVERTISE_10HALF | ADVERTISE_100HALF | ADVERTISE_10FULL | ADVERTISE_100FULL | ADVERTISE_CSMA)); ++ /* Ability advert set : switch device port, 1000BASE-T FD, non-1000BASE-T HD */ ++ /* (Register[0x09] bit 10, 9 = 1, bit 8 = 0 */ ++ egphy28_reg_modify(phy_addr, EGPHY28_MII_CTRL1000, ++ (REPEATER_DTE | ADVERTISE_1000FULL), (REPEATER_DTE | ADVERTISE_1000FULL | ADVERTISE_1000HALF)); ++ ++ /* Set Auto-Negoatiation, Restartr-AN (Register[0x00], bit 12, 9 = 1) */ ++ egphy28_reg_modify(phy_addr, EGPHY28_COPPER_MII_CTRL, (BMCR_ANENABLE | BMCR_ANRESTART), ++ (BMCR_ANENABLE | BMCR_ANRESTART)); ++ ++ /* Clear bit 14 for automatic MDI crossover (Register[RDB 0x00] bit 14 = 0) in default */ ++ egphy28_rdb_reg_modify(phy_addr, 0x00, 0x0, (1 << 14)); ++ ++ /* Clear bit 9 to disable forced auto MDI xover */ ++ egphy28_rdb_reg_modify(phy_addr, 0x2f, 0x0, (1 << 9)); ++#endif ++ ++ return rv; ++} ++ ++ ++int ++egphy28_reset_setup(void __iomem *base, u32 phy_addr) ++{ ++ int rv = SOC_E_NONE; ++ ++ NET_TRACE(("%s enter\n", __FUNCTION__)); ++ ++ rv = egphy28_ge_reset(phy_addr); ++ if (SOC_SUCCESS(rv)) { ++ rv = egphy28_ge_init(base, phy_addr); ++ } ++ ++ return rv; ++} ++ ++int ++egphy28_init(void __iomem *base, u32 phy_addr) ++{ ++ u16 phyid0, phyid1; ++ ++ NET_TRACE(("%s: phy_addr %d\n", __FUNCTION__, phy_addr)); ++ ++ egphy28_reg_read(phy_addr, EGPHY28_PHY_ID_MSB, &phyid0); ++ egphy28_reg_read(phy_addr, EGPHY28_PHY_ID_LSB, &phyid1); ++ ++ printf("%s Phy ChipID: 0x%04x:0x%04x\n", __FUNCTION__, phyid1, phyid0); ++ //egphy28_reset_setup(base, phy_addr); ++ ++ return 0; ++} ++ ++int ++egphy28_enable_set(u32 phy_addr, int enable) ++{ ++ u16 val; ++ ++ NET_TRACE(("%s: phy_addr %d\n", __FUNCTION__, phy_addr)); ++ ++ egphy28_reg_read(phy_addr, EGPHY28_COPPER_MII_CTRL, &val); ++ if (enable) { ++ val &= ~BMCR_PDOWN; ++ } else { ++ val |= BMCR_PDOWN; ++ } ++ egphy28_reg_write(phy_addr, EGPHY28_COPPER_MII_CTRL, val); ++ ++ return SOC_E_NONE; ++} ++ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_phy5221.c b/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_phy5221.c +--- a/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_phy5221.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_phy5221.c 2017-11-09 17:53:44.025293000 +0800 +@@ -0,0 +1,657 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ * ++ * These routines provide access to the external phy ++ * ++ */ ++ ++/* ---- Include Files ---------------------------------------------------- */ ++#include ++#include ++#include "../../../mdio/iproc_mdio.h" ++#include "bcmiproc_phy.h" ++#include "bcmiproc_phy5221.h" ++ ++/* ---- External Variable Declarations ----------------------------------- */ ++/* ---- External Function Prototypes ------------------------------------- */ ++/* ---- Public Variables ------------------------------------------------- */ ++/* ---- Private Constants and Types -------------------------------------- */ ++/* ---- Private Variables ------------------------------------------------ */ ++ ++/* debug/trace */ ++//#define BCMDBG ++//#define BCMDBG_ERR ++#ifdef BCMDBG ++#define NET_ERROR(args) printf args ++#define NET_TRACE(args) printf args ++#elif defined(BCMDBG_ERR) ++#define NET_ERROR(args) printf args ++#define NET_TRACE(args) ++#else ++#define NET_ERROR(args) ++#define NET_TRACE(args) ++#endif /* BCMDBG */ ++#define NET_REG_TRACE(args) ++ ++ ++#ifndef ASSERT ++#define ASSERT(exp) ++#endif ++ ++ ++/* ==== Public Functions ================================================= */ ++ ++int ++phy5221_wr_reg(uint eth_num, uint phyaddr, uint16 reg_bank, ++ uint8 reg_addr, uint16 *data) ++{ ++ uint16 wr_data=*data; ++ uint16 test_reg; ++ ++ NET_TRACE(("%s enter\n", __FUNCTION__)); ++ ++ NET_REG_TRACE(("%s going to write phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", ++ __FUNCTION__, phyaddr, reg_bank, reg_addr, wr_data)); ++ ++ if (reg_bank) { ++ iproc_mii_read(MII_DEV_EXT, phyaddr, 0x1f, &test_reg); ++ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x1f, (test_reg | 0x0080)); ++ ++ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, wr_data); ++ ++ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x1f, test_reg); ++ } else { ++ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, wr_data); ++ } ++ return SOC_E_NONE; ++} ++ ++ ++int ++phy5221_rd_reg(uint eth_num, uint phyaddr, uint16 reg_bank, ++ uint8 reg_addr, uint16 *data) ++{ ++ uint16 test_reg; ++ ++ NET_TRACE(("%s enter\n", __FUNCTION__)); ++ ++ NET_REG_TRACE(("%s going to read phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x)\n", ++ __FUNCTION__, phyaddr, reg_bank, reg_addr)); ++ ++ if (reg_bank) { ++ iproc_mii_read(MII_DEV_EXT, phyaddr, 0x1f, &test_reg); ++ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x1f, (test_reg | 0x0080)); ++ ++ iproc_mii_read(MII_DEV_EXT, phyaddr, reg_addr, data); ++ ++ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x1f, test_reg); ++ } else { ++ iproc_mii_read(MII_DEV_EXT, phyaddr, reg_addr, data); ++ } ++ NET_REG_TRACE(("%s rd phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", ++ __FUNCTION__, phyaddr, reg_bank, reg_addr, *data)); ++ ++ return SOC_E_NONE; ++} ++ ++ ++int ++phy5221_mod_reg(uint eth_num, uint phyaddr, uint16 reg_bank, ++ uint8 reg_addr, uint16 data, uint16 mask) ++{ ++ uint16 test_reg; ++ uint16 org_data, rd_data; ++ ++ NET_TRACE(("%s enter\n", __FUNCTION__)); ++ ++ NET_REG_TRACE(("%s going to modify phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x) mask(0x%x)\n", ++ __FUNCTION__, phyaddr, reg_bank, reg_addr, data, mask)); ++ ++ if (reg_bank) { ++ iproc_mii_read(MII_DEV_EXT, phyaddr, 0x1f, &test_reg); ++ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x1f, (test_reg | 0x0080)); ++ ++ iproc_mii_read(MII_DEV_EXT, phyaddr, reg_addr, &rd_data); ++ NET_REG_TRACE(("%s rd phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", ++ __FUNCTION__, phyaddr, reg_bank, reg_addr, rd_data)); ++ org_data = rd_data; ++ rd_data &= ~(mask); ++ rd_data |= data; ++ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, rd_data); ++ NET_REG_TRACE(("%s wrt phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", ++ __FUNCTION__, phyaddr, reg_bank, reg_addr, rd_data)); ++ ++ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x1f, test_reg); ++ } else { ++ iproc_mii_read(MII_DEV_EXT, phyaddr, reg_addr, &rd_data); ++ NET_REG_TRACE(("%s rd phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", ++ __FUNCTION__, phyaddr, reg_bank, reg_addr, rd_data)); ++ org_data = rd_data; ++ rd_data &= ~(mask); ++ rd_data |= data; ++ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, rd_data); ++ NET_REG_TRACE(("%s wrt phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", ++ __FUNCTION__, phyaddr, reg_bank, reg_addr, rd_data)); ++ } ++ ++ return SOC_E_NONE; ++} ++ ++ ++void ++phy5221_fe_reset(uint eth_num, uint phyaddr) ++{ ++ uint16 ctrl; ++ ++ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); ++ ++ /* set reset flag */ ++ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &ctrl); ++ ctrl |= MII_CTRL_RESET; ++ phy5221_wr_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &ctrl); ++ ++ SPINWAIT( (!phy5221_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &ctrl) ++ && (ctrl & MII_CTRL_RESET)), 100000); ++ /* check if out of reset */ ++ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &ctrl); ++ if (ctrl & MII_CTRL_RESET) { ++ /* timeout */ ++ NET_ERROR(("et%d: %s reset not complete\n", eth_num, __FUNCTION__)); ++ } else { ++ NET_ERROR(("et%d: %s reset complete\n", eth_num, __FUNCTION__)); ++ } ++ ++ return; ++} ++ ++ ++/* ++ * Function: ++ * phy5221_fe_init ++ * Purpose: ++ * Initialize the PHY (MII mode) to a known good state. ++ * Parameters: ++ * unit - StrataSwitch unit #. ++ * port - StrataSwitch port #. ++ * Returns: ++ * SOC_E_XXX ++ ++ * Notes: ++ * No synchronization performed at this level. ++ */ ++int ++phy5221_fe_init(uint eth_num, uint phyaddr) ++{ ++ uint16 mii_ana, mii_ctrl; ++ ++ /* Reset PHY */ ++ phy5221_fe_reset(eth_num, phyaddr); ++ ++ mii_ana = MII_ANA_HD_10 | MII_ANA_FD_10 | MII_ANA_HD_100 | ++ MII_ANA_FD_100 | MII_ANA_ASF_802_3; ++ mii_ctrl = MII_CTRL_FD | MII_CTRL_SS_100 | MII_CTRL_AE | MII_CTRL_RAN; ++ ++ phy5221_wr_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); ++ phy5221_wr_reg(eth_num, phyaddr, PHY_MII_ANAr_BANK, PHY_MII_ANAr_ADDR, &mii_ana); ++ ++ return SOC_E_NONE; ++} ++ ++ ++#ifdef BCMINTERNAL ++/* ++ * Function: ++ * phy5221_fe_speed_set ++ * Purpose: ++ * Set the current operating speed (forced). ++ * Parameters: ++ * unit - StrataSwitch unit #. ++ * port - StrataSwitch port #. ++ * duplex - (OUT) Boolean, true indicates full duplex, false ++ * indicates half. ++ * Returns: ++ * SOC_E_XXX ++ * Notes: ++ * No synchronization performed at this level. Autonegotiation is ++ * not manipulated. ++ */ ++int ++phy5221_fe_speed_set(uint eth_num, uint phyaddr, int speed) ++{ ++ uint16 mii_ctrl; ++ ++ if (speed == 0) { ++ return SOC_E_NONE; ++ } ++ ++ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); ++ ++ mii_ctrl &= ~(MII_CTRL_SS_LSB | MII_CTRL_SS_MSB); ++ switch(speed) { ++ case 10: ++ mii_ctrl |= MII_CTRL_SS_10; ++ break; ++ case 100: ++ mii_ctrl |= MII_CTRL_SS_100; ++ break; ++ case 1000: ++ mii_ctrl |= MII_CTRL_SS_1000; ++ break; ++ default: ++ return SOC_E_CONFIG; ++ } ++ ++ phy5221_wr_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); ++ ++ return SOC_E_NONE; ++} ++#endif /* BCMINTERNAL */ ++ ++ ++/* ++ * Function: ++ * phy5221_init ++ * Purpose: ++ * Initialize xgxs6 phys ++ * Parameters: ++ * eth_num - ethernet data ++ * phyaddr - physical address ++ * Returns: ++ * 0 ++ */ ++int ++phy5221_init(uint eth_num, uint phyaddr) ++{ ++ uint16 phyid0, phyid1; ++ ++ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); ++ ++ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_PHY_ID0r_BANK, PHY_MII_PHY_ID0r_ADDR, &phyid0); ++ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_PHY_ID1r_BANK, PHY_MII_PHY_ID1r_ADDR, &phyid1); ++ ++ NET_TRACE(("%s phyaddr(0x%x) Phy ChipID: 0x%04x:0x%04x\n", __FUNCTION__, phyaddr, phyid1, phyid0)); ++ ++ phy5221_fe_init(eth_num, phyaddr); ++ ++ return 0; ++} ++ ++/* ++ * Function: ++ * phy5221_link_get ++ * Purpose: ++ * Determine the current link up/down status ++ * Parameters: ++ * unit - StrataSwitch unit #. ++ * port - StrataSwitch port #. ++ * link - (OUT) Boolean, true indicates link established. ++ * Returns: ++ * SOC_E_XXX ++ * Notes: ++ * No synchronization performed at this level. ++ */ ++int ++phy5221_link_get(uint eth_num, uint phyaddr, int *link) ++{ ++ uint16 mii_ctrl, mii_stat; ++ uint32 wait; ++ ++ *link = FALSE; /* Default */ ++ ++ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &mii_stat); ++ /* the first read of status register will not show link up, second read will show link up */ ++ if (!(mii_stat & MII_STAT_LA) ) { ++ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &mii_stat); ++ } ++ ++ if (!(mii_stat & MII_STAT_LA) || (mii_stat == 0xffff)) { ++ /* mii_stat == 0xffff check is to handle removable PHY daughter cards */ ++ return SOC_E_NONE; ++ } ++ ++ /* Link appears to be up; we are done if autoneg is off. */ ++ ++ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); ++ ++ if (!(mii_ctrl & MII_CTRL_AE)) { ++ *link = TRUE; ++ return SOC_E_NONE; ++ } ++ ++ /* ++ * If link appears to be up but autonegotiation is still in ++ * progress, wait for it to complete. For BCM5228, autoneg can ++ * still be busy up to about 200 usec after link is indicated. Also ++ * continue to check link state in case it goes back down. ++ * wait 500ms (500000us/10us = 50000 ) ++ */ ++ for (wait=0; wait<50000; wait++) { ++ ++ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &mii_stat); ++ ++ if (!(mii_stat & MII_STAT_LA)) { ++ /* link is down */ ++ return SOC_E_NONE; ++ } ++ ++ if (mii_stat & MII_STAT_AN_DONE) { ++ /* AutoNegotiation done */ ++ break; ++ } ++ ++ OSL_DELAY(10); ++ } ++ if (wait>=50000) { ++ /* timeout */ ++ return SOC_E_BUSY; ++ } ++ ++ /* Return link state at end of polling */ ++ *link = ((mii_stat & MII_STAT_LA) != 0); ++ ++ return SOC_E_NONE; ++} ++ ++ ++/* ++ * Function: ++ * phy5221_enable_set ++ * Purpose: ++ * Enable/Disable phy ++ * Parameters: ++ * eth_num - ethernet data ++ * phyaddr - physical address ++ * enable - on/off state to set ++ * Returns: ++ * 0 ++ */ ++int ++phy5221_enable_set(uint eth_num, uint phyaddr, int enable) ++{ ++ uint16 data; /* New value to write to PHY register */ ++ ++ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); ++ ++ data = enable ? 0 : MII_ECR_TD; /* Transmitt enable/disable */ ++ phy5221_mod_reg(eth_num, phyaddr, PHY_MII_ECRr_BANK, PHY_MII_ECRr_ADDR, data, MII_ECR_TD); ++ ++ data = enable ? 0 : PHY522X_SUPER_ISOLATE_MODE; ++ /* Device needs to be put in super-isolate mode in order to disable ++ * the link in 10BaseT mode ++ */ ++ phy5221_mod_reg(eth_num, phyaddr, PHY_AUX_MULTIPLE_PHYr_BANK, PHY_AUX_MULTIPLE_PHYr_ADDR, ++ data, PHY522X_SUPER_ISOLATE_MODE); ++ ++ return SOC_E_NONE; ++} ++ ++ ++#ifdef BCMINTERNAL ++/* ++ * Function: ++ * phy5221_speed_set ++ * Purpose: ++ * Set PHY speed ++ * Parameters: ++ * eth_num - ethernet data ++ * phyaddr - physical address ++ * speed - link speed in Mbps ++ * Returns: ++ * 0 ++ */ ++int ++phy5221_speed_set(uint eth_num, uint phyaddr, int speed) ++{ ++ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); ++ ++ phy5221_fe_speed_set(eth_num, phyaddr, speed); ++ ++ return 0; ++} ++#endif /* BCMINTERNAL */ ++ ++ ++/* ++ * Function: ++ * phy5221_auto_negotiate_gcd (greatest common denominator). ++ * Purpose: ++ * Determine the current greatest common denominator between ++ * two ends of a link ++ * Parameters: ++ * unit - StrataSwitch unit #. ++ * port - StrataSwitch port #. ++ * speed - (OUT) greatest common speed. ++ * duplex - (OUT) greatest common duplex. ++ * link - (OUT) Boolean, true indicates link established. ++ * Returns: ++ * SOC_E_XXX ++ * Notes: ++ * No synchronization performed at this level. ++ */ ++static int ++phy5221_auto_negotiate_gcd(uint eth_num, uint phyaddr, int *speed, int *duplex) ++{ ++ int t_speed, t_duplex; ++ uint16 mii_ana, mii_anp, mii_stat; ++ uint16 mii_gb_stat, mii_esr, mii_gb_ctrl; ++ ++ mii_gb_stat = 0; /* Start off 0 */ ++ mii_gb_ctrl = 0; /* Start off 0 */ ++ ++ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_ANAr_BANK, PHY_MII_ANAr_ADDR, &mii_ana); ++ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_ANPr_BANK, PHY_MII_ANPr_ADDR, &mii_anp); ++ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &mii_stat); ++ ++ if (mii_stat & MII_STAT_ES) { /* Supports extended status */ ++ /* ++ * If the PHY supports extended status, check if it is 1000MB ++ * capable. If it is, check the 1000Base status register to see ++ * if 1000MB negotiated. ++ */ ++ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_ESRr_BANK, PHY_MII_ESRr_ADDR, &mii_esr); ++ ++ if (mii_esr & (MII_ESR_1000_X_FD | MII_ESR_1000_X_HD | ++ MII_ESR_1000_T_FD | MII_ESR_1000_T_HD)) { ++ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_GB_STATr_BANK, PHY_MII_GB_STATr_ADDR, &mii_gb_stat); ++ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_GB_CTRLr_BANK, PHY_MII_GB_CTRLr_ADDR, &mii_gb_ctrl); ++ } ++ } ++ ++ /* ++ * At this point, if we did not see Gig status, one of mii_gb_stat or ++ * mii_gb_ctrl will be 0. This will cause the first 2 cases below to ++ * fail and fall into the default 10/100 cases. ++ */ ++ ++ mii_ana &= mii_anp; ++ ++ if ((mii_gb_ctrl & MII_GB_CTRL_ADV_1000FD) && ++ (mii_gb_stat & MII_GB_STAT_LP_1000FD)) { ++ t_speed = 1000; ++ t_duplex = 1; ++ } else if ((mii_gb_ctrl & MII_GB_CTRL_ADV_1000HD) && ++ (mii_gb_stat & MII_GB_STAT_LP_1000HD)) { ++ t_speed = 1000; ++ t_duplex = 0; ++ } else if (mii_ana & MII_ANA_FD_100) { /* [a] */ ++ t_speed = 100; ++ t_duplex = 1; ++ } else if (mii_ana & MII_ANA_T4) { /* [b] */ ++ t_speed = 100; ++ t_duplex = 0; ++ } else if (mii_ana & MII_ANA_HD_100) { /* [c] */ ++ t_speed = 100; ++ t_duplex = 0; ++ } else if (mii_ana & MII_ANA_FD_10) { /* [d] */ ++ t_speed = 10; ++ t_duplex = 1 ; ++ } else if (mii_ana & MII_ANA_HD_10) { /* [e] */ ++ t_speed = 10; ++ t_duplex = 0; ++ } else { ++ return(SOC_E_FAIL); ++ } ++ ++ if (speed) *speed = t_speed; ++ if (duplex) *duplex = t_duplex; ++ ++ return(SOC_E_NONE); ++} ++ ++ ++/* ++ * Function: ++ * phy5221_speed_get ++ * Purpose: ++ * Get PHY speed ++ * Parameters: ++ * eth_num - ethernet data ++ * phyaddr - physical address ++ * speed - current link speed in Mbps ++ * Returns: ++ * 0 ++ */ ++int ++phy5221_speed_get(uint eth_num, uint phyaddr, int *speed, int *duplex) ++{ ++ int rv; ++ uint16 mii_ctrl, mii_stat; ++ ++ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); ++ ++ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); ++ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &mii_stat); ++ ++ *speed = 0; ++ *duplex = 0; ++ if (mii_ctrl & MII_CTRL_AE) { /* Auto-negotiation enabled */ ++ if (!(mii_stat & MII_STAT_AN_DONE)) { /* Auto-neg NOT complete */ ++ rv = SOC_E_NONE; ++ } else { ++ rv = phy5221_auto_negotiate_gcd(eth_num, phyaddr, speed, duplex); ++ } ++ } else { /* Auto-negotiation disabled */ ++ /* ++ * Simply pick up the values we force in CTRL register. ++ */ ++ if (mii_ctrl & MII_CTRL_FD) ++ *duplex = 1; ++ ++ switch(MII_CTRL_SS(mii_ctrl)) { ++ case MII_CTRL_SS_10: ++ *speed = 10; ++ break; ++ case MII_CTRL_SS_100: ++ *speed = 100; ++ break; ++ case MII_CTRL_SS_1000: ++ *speed = 1000; ++ break; ++ default: /* Just pass error back */ ++ return(SOC_E_UNAVAIL); ++ } ++ rv = SOC_E_NONE; ++ } ++ ++ return(rv); ++} ++ ++ ++#ifdef BCMINTERNAL ++int ++phy5221_lb_set(uint eth_num, uint phyaddr, int enable) ++{ ++ uint16 mii_ctrl; ++ ++ /* set reset flag */ ++ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); ++ mii_ctrl &= ~MII_CTRL_LE; ++ mii_ctrl |= enable ? MII_CTRL_LE : 0; ++ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); ++ ++ return 0; ++} ++#endif /* BCMINTERNAL */ ++ ++ ++#ifdef BCMINTERNAL ++void ++phy5221_disp_status(uint eth_num, uint phyaddr) ++{ ++ uint16 tmp0, tmp1, tmp2; ++ int speed, duplex; ++ ++ printf("et%d: %s: phyaddr:%d\n", eth_num, __FUNCTION__, phyaddr); ++ ++ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &tmp0); ++ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &tmp1); ++ printf(" MII-Control: 0x%x; MII-Status: 0x%x\n", tmp0, tmp1); ++ ++ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_PHY_ID0r_BANK, PHY_MII_PHY_ID0r_ADDR, &tmp0); ++ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_PHY_ID1r_BANK, PHY_MII_PHY_ID1r_ADDR, &tmp1); ++ printf(" Phy ChipID: 0x%04x:0x%04x\n", tmp0, tmp1); ++ ++ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_ANAr_BANK, PHY_MII_ANAr_ADDR, &tmp0); ++ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_ANPr_BANK, PHY_MII_ANPr_ADDR, &tmp1); ++ phy5221_speed_get(eth_num, phyaddr, &speed, &duplex); ++ printf(" AutoNeg Ad: 0x%x; AutoNeg Partner: 0x%x; speed:%d; duplex:%d\n", tmp0, tmp1, speed, duplex); ++ ++ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_ESRr_BANK, PHY_MII_ESRr_ADDR, &tmp0); ++ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_ECRr_BANK, PHY_MII_ECRr_ADDR, &tmp1); ++ phy5221_rd_reg(eth_num, phyaddr, 0x0000, 0x11, &tmp2); ++ printf(" Reg0x0f: 0x%x; 100Base-X AUX ctrl: 0x%x; 100Base-X AUX stat: 0x%x\n", tmp0, tmp1, tmp2); ++ ++ phy5221_rd_reg(eth_num, phyaddr, 0x0000, 0x12, &tmp0); ++ phy5221_rd_reg(eth_num, phyaddr, 0x0000, 0x13, &tmp1); ++ phy5221_rd_reg(eth_num, phyaddr, 0x0000, 0x14, &tmp2); ++ printf(" 100Base-X RCV ERR: 0x%x; 100Base-X FALSE CARRIER: 0x%x; 100Base-X DISCON: 0x%x\n", tmp0, tmp1, tmp2); ++} ++#endif /* BCMINTERNAL */ ++ ++ ++#ifdef BCMINTERNAL ++void ++phy5221_chk_err(uint eth_num, uint phyaddr) ++{ ++ uint16 tmp0; ++ ++ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &tmp0); ++ if (!(tmp0 & MII_STAT_LA)) { ++ printf("ERROR: reg 0x01 (LINK down): 0x%x\n", tmp0); ++ } ++ if (tmp0 & (MII_STAT_JBBR|MII_STAT_RF)) { ++ printf("ERROR: reg 0x01: 0x%x\n", tmp0); ++ } ++ ++ phy5221_rd_reg(eth_num, phyaddr, 0, 0x11, &tmp0); ++ if (!(tmp0 & 0x100)) { ++ printf("ERROR: reg 0x11 (LINK down): 0x%x\n", tmp0); ++ } ++ if (tmp0 & 0x8bf) { ++ printf("ERROR: reg 0x11: 0x%x\n", tmp0); ++ } ++ ++ phy5221_rd_reg(eth_num, phyaddr, 0, 0x12, &tmp0); ++ if (tmp0) { ++ printf("ERROR: reg 0x12 (RCV ERR CNT): 0x%x\n", tmp0); ++ } ++ ++ phy5221_rd_reg(eth_num, phyaddr, 0, 0x13, &tmp0); ++ if (tmp0) { ++ printf("ERROR: reg 0x13 (FALSE CARRIER CNT): 0x%x\n", tmp0); ++ } ++ ++ phy5221_rd_reg(eth_num, phyaddr, 0, 0x14, &tmp0); ++ if (tmp0 & 0xc000) { ++ printf("ERROR: reg 0x14: 0x%x\n", tmp0); ++ } ++ ++ phy5221_rd_reg(eth_num, phyaddr, 0, 0x19, &tmp0); ++ if (!(tmp0 & 0x4)) { ++ printf("ERROR: reg 0x19 (LINK down): 0x%x\n", tmp0); ++ } ++ if (tmp0 & 0xc0) { ++ printf("ERROR: reg 0x19: 0x%x\n", tmp0); ++ } ++} ++#endif /* BCMINTERNAL */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_phy5461s.c b/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_phy5461s.c +--- a/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_phy5461s.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_phy5461s.c 2017-11-09 17:53:44.027292000 +0800 +@@ -0,0 +1,896 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ * ++ * These routines provide access to the external phy ++ * ++ */ ++ ++/* ---- Include Files ---------------------------------------------------- */ ++#include ++#include ++#include "../../../mdio/iproc_mdio.h" ++#include "bcmiproc_phy.h" ++#include "bcmiproc_phy5461s.h" ++ ++/* ---- External Variable Declarations ----------------------------------- */ ++/* ---- External Function Prototypes ------------------------------------- */ ++/* ---- Public Variables ------------------------------------------------- */ ++/* ---- Private Constants and Types -------------------------------------- */ ++/* ---- Private Variables ------------------------------------------------ */ ++ ++/* debug/trace */ ++//#define BCMDBG ++//#define BCMDBG_ERR ++#ifdef BCMDBG ++#define NET_ERROR(args) printf args ++#define NET_TRACE(args) printf args ++#elif defined(BCMDBG_ERR) ++#define NET_ERROR(args) printf args ++#define NET_TRACE(args) ++#else ++#define NET_ERROR(args) ++#define NET_TRACE(args) ++#endif /* BCMDBG */ ++#define NET_REG_TRACE(args) ++ ++ ++#ifndef ASSERT ++#define ASSERT(exp) ++#endif ++ ++ ++/* ==== Public Functions ================================================= */ ++ ++int ++phy5461_wr_reg(uint eth_num, uint phyaddr, uint32 flags, uint16 reg_bank, ++ uint8 reg_addr, uint16 *data) ++{ ++ int rv = SOC_E_NONE; ++ uint16 wr_data=*data; ++ ++ NET_TRACE(("%s enter\n", __FUNCTION__)); ++ ++ NET_REG_TRACE(("%s going to write phyaddr(0x%x) flags(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", ++ __FUNCTION__, phyaddr, flags, reg_bank, reg_addr, wr_data)); ++ //printf("%s phyaddr(0x%x) flags(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", ++ // __FUNCTION__, phyaddr, flags, reg_bank, reg_addr, wr_data); ++ ++ if (flags & SOC_PHY_REG_1000X) { ++ if (reg_addr <= 0x000f) { ++ uint16 blk_sel; ++ ++ /* Map 1000X page */ ++ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x1c, 0x7c00); ++ ++ iproc_mii_read(MII_DEV_EXT, phyaddr, 0x1c, &blk_sel); ++ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x1c, blk_sel | 0x8001); ++ ++ /* write 1000X IEEE register */ ++ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, wr_data); ++ ++ /* Restore IEEE mapping */ ++ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x1c, (blk_sel & 0xfffe) | 0x8000); ++ } else if (flags & _SOC_PHY_REG_DIRECT) { ++ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, wr_data); ++ } else { ++ rv = SOC_E_PARAM; ++ } ++ } else { ++ switch(reg_addr) { ++ /* Map shadow registers */ ++#ifdef BCMINTERNAL ++ case 0x15: ++ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x17, reg_bank); ++ break; ++#endif /* BCMINTERNAL */ ++ case 0x18: ++ if (reg_bank <= 0x0007) { ++ if (reg_bank == 0x0007) { ++ wr_data |= 0x8000; ++ } ++ wr_data = (wr_data & ~(0x0007)) | reg_bank; ++ } else { ++ rv = SOC_E_PARAM; ++ } ++ break; ++ case 0x1C: ++ if (reg_bank <= 0x001F) { ++ wr_data = 0x8000 | (reg_bank << 10) | (wr_data & 0x03FF); ++ } else { ++ rv = SOC_E_PARAM; ++ } ++ break; ++#ifdef BCMINTERNAL ++ case 0x1D: ++ if (reg_bank == 0x0000) { ++ wr_data = wr_data & 0x07FFF; ++ } else { ++ rv = SOC_E_PARAM; ++ } ++ break; ++#endif /* BCMINTERNAL */ ++ default: ++ if (!(flags & SOC_PHY_REG_RESERVE_ACCESS)) { ++ /* Must not write to reserved registers */ ++ if (reg_addr > 0x001e) { ++ rv = SOC_E_PARAM; ++ } ++ } ++ break; ++ } ++ if (SOC_SUCCESS(rv)) { ++ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, wr_data); ++ } ++ } ++ if (SOC_FAILURE(rv)) { ++ NET_ERROR(("%s ERROR phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) rv(%d)\n", ++ __FUNCTION__, phyaddr, reg_bank, reg_addr, rv)); ++ } ++ return rv; ++} ++ ++ ++int ++phy5461_rd_reg(uint eth_num, uint phyaddr, uint32 flags, uint16 reg_bank, ++ uint8 reg_addr, uint16 *data) ++{ ++ int rv = SOC_E_NONE; ++ ++ NET_TRACE(("%s enter\n", __FUNCTION__)); ++ ++ NET_REG_TRACE(("%s going to read phyaddr(0x%x) flags(0x%x) reg_bank(0x%x) reg_addr(0x%x)\n", ++ __FUNCTION__, phyaddr, flags, reg_bank, reg_addr)); ++ if (flags & SOC_PHY_REG_1000X) { ++ if (reg_addr <= 0x000f) { ++ uint16 blk_sel; ++ ++ /* Map 1000X page */ ++ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x1c, 0x7c00); ++ iproc_mii_read(MII_DEV_EXT, phyaddr, 0x1c, &blk_sel); ++ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x1c, blk_sel | 0x8001); ++ ++ /* Read 1000X IEEE register */ ++ iproc_mii_read(MII_DEV_EXT, phyaddr, reg_addr, data); ++ NET_REG_TRACE(("%s rd phyaddr(0x%x) flags(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", ++ __FUNCTION__, phyaddr, flags, reg_bank, reg_addr, *data)); ++ ++ /* Restore IEEE mapping */ ++ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x1c, (blk_sel & 0xfffe) | 0x8000); ++ } else { ++ rv = SOC_E_PARAM; ++ } ++ } else { ++ switch(reg_addr) { ++ /* Map shadow registers */ ++#ifdef BCMINTERNAL ++ case 0x15: ++ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x17, reg_bank); ++ break; ++#endif /* BCMINTERNAL */ ++ case 0x18: ++ if (reg_bank <= 0x0007) { ++ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, (reg_bank << 12) | 0x7); ++ } else { ++ rv = SOC_E_PARAM; ++ } ++ break; ++ case 0x1C: ++ if (reg_bank <= 0x001F) { ++ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, (reg_bank << 10)); ++ } else { ++ rv = SOC_E_PARAM; ++ } ++ break; ++#ifdef BCMINTERNAL ++ case 0x1D: ++ if (reg_bank <= 0x0001) { ++ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, (reg_bank << 15)); ++ } else { ++ rv = SOC_E_PARAM; ++ } ++ break; ++#endif /* BCMINTERNAL */ ++ default: ++ if (!(flags & SOC_PHY_REG_RESERVE_ACCESS)) { ++ /* Must not read from reserved registers */ ++ if (reg_addr > 0x001e) { ++ rv = SOC_E_PARAM; ++ } ++ } ++ break; ++ } ++ if (SOC_SUCCESS(rv)) { ++ iproc_mii_read(MII_DEV_EXT, phyaddr, reg_addr, data); ++ NET_REG_TRACE(("%s rd phyaddr(0x%x) flags(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", ++ __FUNCTION__, phyaddr, flags, reg_bank, reg_addr, *data)); ++ } ++ } ++ if (SOC_FAILURE(rv)) { ++ NET_ERROR(("%s ERROR phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) rv(%d)\n", ++ __FUNCTION__, phyaddr, reg_bank, reg_addr, rv)); ++ } else { ++ //printf("%s phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", ++ // __FUNCTION__, phyaddr, reg_bank, reg_addr, *data); ++ } ++ ++ return rv; ++} ++ ++ ++int ++phy5461_mod_reg(uint eth_num, uint phyaddr, uint32 flags, uint16 reg_bank, ++ uint8 reg_addr, uint16 data, uint16 mask) ++{ ++ int rv = SOC_E_NONE; ++ uint16 org_data, rd_data; ++ ++ NET_TRACE(("%s enter\n", __FUNCTION__)); ++ ++ NET_REG_TRACE(("%s going to modify phyaddr(0x%x) flags(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x) mask(0x%x)\n", ++ __FUNCTION__, phyaddr, flags, reg_bank, reg_addr, data, mask)); ++ ++ if (flags & SOC_PHY_REG_1000X) { ++ if (reg_addr <= 0x000f) { ++ uint16 blk_sel; ++ ++ /* Map 1000X page */ ++ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x1c, 0x7c00); ++ iproc_mii_read(MII_DEV_EXT, phyaddr, 0x1c, &blk_sel); ++ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x1c, blk_sel | 0x8001); ++ ++ /* Modify 1000X IEEE register */ ++ iproc_mii_read(MII_DEV_EXT, phyaddr, reg_addr, &rd_data); ++ NET_REG_TRACE(("%s rd phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", ++ __FUNCTION__, phyaddr, reg_bank, reg_addr, rd_data)); ++ org_data = rd_data; ++ rd_data &= ~(mask); ++ rd_data |= data; ++ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, rd_data); ++ NET_REG_TRACE(("%s wrt phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", ++ __FUNCTION__, phyaddr, reg_bank, reg_addr, rd_data)); ++ ++ /* Restore IEEE mapping */ ++ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x1c, (blk_sel & 0xfffe) | 0x8000); ++ } else { ++ rv = SOC_E_PARAM; ++ } ++ } else { ++ switch(reg_addr) { ++ /* Map shadow registers */ ++#ifdef BCMINTERNAL ++ case 0x15: ++ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x17, reg_bank); ++ break; ++#endif /* BCMINTERNAL */ ++ case 0x18: ++ if (reg_bank <= 0x0007) { ++ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, (reg_bank << 12) | 0x7); ++ ++ if (reg_bank == 0x0007) { ++ data |= 0x8000; ++ mask |= 0x8000; ++ } ++ mask &= ~(0x0007); ++ } else { ++ rv = SOC_E_PARAM; ++ } ++ break; ++ case 0x1C: ++ if (reg_bank <= 0x001F) { ++ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, (reg_bank << 10)); ++ data |= 0x8000; ++ mask |= 0x8000; ++ mask &= ~(0x1F << 10); ++ } else { ++ rv = SOC_E_PARAM; ++ } ++ break; ++#ifdef BCMINTERNAL ++ case 0x1D: ++ if (reg_bank == 0x0000) { ++ mask &= 0x07FFF; ++ } else { ++ rv = SOC_E_PARAM; ++ } ++ break; ++#endif /* BCMINTERNAL */ ++ default: ++ if (!(flags & SOC_PHY_REG_RESERVE_ACCESS)) { ++ /* Must not write to reserved registers */ ++ if (reg_addr > 0x001e) { ++ rv = SOC_E_PARAM; ++ } ++ } ++ break; ++ } ++ if (SOC_SUCCESS(rv)) { ++ iproc_mii_read(MII_DEV_EXT, phyaddr, reg_addr, &rd_data); ++ NET_REG_TRACE(("%s rd phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", ++ __FUNCTION__, phyaddr, reg_bank, reg_addr, rd_data)); ++ org_data = rd_data; ++ rd_data &= ~(mask); ++ rd_data |= data; ++ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, rd_data); ++ NET_REG_TRACE(("%s wrt phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", ++ __FUNCTION__, phyaddr, reg_bank, reg_addr, rd_data)); ++ } ++ } ++ ++ if (SOC_FAILURE(rv)) { ++ NET_ERROR(("%s ERROR phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) rv(%d)\n", ++ __FUNCTION__, phyaddr, reg_bank, reg_addr, rv)); ++ } else { ++ //printf("%s modified(0x%x to 0x%x at phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x)\n", ++ // __FUNCTION__, org_data, rd_data, phyaddr, reg_bank, reg_addr); ++ } ++ ++ return rv; ++} ++ ++ ++void ++phy5461_ge_reset(uint eth_num, uint phyaddr) ++{ ++ uint16 ctrl; ++ ++ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); ++ ++ /* set reset flag */ ++ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_FLAGS, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &ctrl); ++ ctrl |= MII_CTRL_RESET; ++ phy5461_wr_reg(eth_num, phyaddr, PHY_MII_CTRLr_FLAGS, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &ctrl); ++ ++ SPINWAIT( (!phy5461_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_FLAGS, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &ctrl) ++ && (ctrl & MII_CTRL_RESET)), 100000); ++ /* check if out of reset */ ++ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_FLAGS, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &ctrl); ++ if (ctrl & MII_CTRL_RESET) { ++ /* timeout */ ++ NET_ERROR(("et%d: %s reset not complete\n", eth_num, __FUNCTION__)); ++ } else { ++ NET_TRACE(("et%d: %s reset complete\n", eth_num, __FUNCTION__)); ++ } ++} ++ ++ ++/* ++ * Function: ++ * phy5461_ge_interface_set ++ * Purpose: ++ * Set the current operating mode of the PHY. ++ * (Pertaining to the MAC/PHY interface, not the line interface). ++ * For example: TBI or MII/GMII. ++ * Parameters: ++ * unit - StrataSwitch unit #. ++ * port - StrataSwitch port #. ++ * pif - one of SOC_PORT_IF_* ++ * Returns: ++ * SOC_E_XXX ++ */ ++int ++phy5461_ge_interface_set(uint eth_num, uint phyaddr, soc_port_if_t pif) ++{ ++ uint16 mii_ecr; ++ int mii; /* MII if true, TBI otherwise */ ++ ++ switch (pif) { ++ case SOC_PORT_IF_MII: ++ case SOC_PORT_IF_GMII: ++ case SOC_PORT_IF_SGMII: ++ mii = TRUE; ++ break; ++ case SOC_PORT_IF_NOCXN: ++ return (SOC_E_NONE); ++ case SOC_PORT_IF_TBI: ++ mii = FALSE; ++ break; ++ default: ++ return SOC_E_UNAVAIL; ++ } ++ ++ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_ECRr_FLAGS, PHY_MII_ECRr_BANK, PHY_MII_ECRr_ADDR, &mii_ecr); ++ ++ if (mii) { ++ mii_ecr &= ~MII_ECR_10B; ++ } else { ++ mii_ecr |= MII_ECR_10B; ++ } ++ ++ phy5461_wr_reg(eth_num, phyaddr, PHY_MII_ECRr_FLAGS, PHY_MII_ECRr_BANK, PHY_MII_ECRr_ADDR, &mii_ecr); ++ ++ return(SOC_E_NONE); ++} ++ ++ ++/* ++ * Function: ++ * phy5461_ge_init ++ * Purpose: ++ * Initialize the PHY (MII mode) to a known good state. ++ * Parameters: ++ * unit - StrataSwitch unit #. ++ * port - StrataSwitch port #. ++ * Returns: ++ * SOC_E_XXX ++ ++ * Notes: ++ * No synchronization performed at this level. ++ */ ++int ++phy5461_ge_init(uint eth_num, uint phyaddr) ++{ ++ uint16 mii_ctrl, mii_gb_ctrl; ++ uint16 mii_ana; ++ soc_port_if_t pif; ++ ++ /* Reset PHY */ ++ phy5461_ge_reset(eth_num, phyaddr); ++ ++ /* set advertized bits */ ++ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_ANAr_FLAGS, PHY_MII_ANAr_BANK, PHY_MII_ANAr_ADDR, &mii_ana); ++ mii_ana |= MII_ANA_FD_100 | MII_ANA_FD_10; ++ mii_ana |= MII_ANA_HD_100 | MII_ANA_HD_10; ++ phy5461_wr_reg(eth_num, phyaddr, PHY_MII_ANAr_FLAGS, PHY_MII_ANAr_BANK, PHY_MII_ANAr_ADDR, &mii_ana); ++ ++ mii_ctrl = MII_CTRL_FD | MII_CTRL_SS_1000 | MII_CTRL_AE | MII_CTRL_RAN; ++ mii_gb_ctrl = MII_GB_CTRL_ADV_1000FD | MII_GB_CTRL_PT; ++ ++ pif = SOC_PORT_IF_GMII; ++ ++ phy5461_ge_interface_set(eth_num, phyaddr, pif); ++ ++ phy5461_wr_reg(eth_num, phyaddr, PHY_MII_GB_CTRLr_FLAGS, PHY_MII_GB_CTRLr_BANK, PHY_MII_GB_CTRLr_ADDR, &mii_gb_ctrl); ++ phy5461_wr_reg(eth_num, phyaddr, PHY_MII_CTRLr_FLAGS, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); ++ ++ return(SOC_E_NONE); ++} ++ ++ ++#ifdef BCMINTERNAL ++/* ++ * Function: ++ * phy5461_ge_speed_set ++ * Purpose: ++ * Set the current operating speed (forced). ++ * Parameters: ++ * unit - StrataSwitch unit #. ++ * port - StrataSwitch port #. ++ * duplex - (OUT) Boolean, true indicates full duplex, false ++ * indicates half. ++ * Returns: ++ * SOC_E_XXX ++ * Notes: ++ * No synchronization performed at this level. Autonegotiation is ++ * not manipulated. ++ */ ++int ++phy5461_ge_speed_set(uint eth_num, uint phyaddr, int speed) ++{ ++ uint16 mii_ctrl; ++ ++ if (speed == 0) { ++ return SOC_E_NONE; ++ } ++ ++ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_FLAGS, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); ++ ++ mii_ctrl &= ~(MII_CTRL_SS_LSB | MII_CTRL_SS_MSB); ++ switch(speed) { ++ case 10: ++ mii_ctrl |= MII_CTRL_SS_10; ++ break; ++ case 100: ++ mii_ctrl |= MII_CTRL_SS_100; ++ break; ++ case 1000: ++ mii_ctrl |= MII_CTRL_SS_1000; ++ break; ++ default: ++ return SOC_E_CONFIG; ++ } ++ ++ phy5461_wr_reg(eth_num, phyaddr, PHY_MII_CTRLr_FLAGS, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); ++ ++ return SOC_E_NONE; ++} ++#endif /* BCMINTERNAL */ ++ ++ ++void ++phy5461_reset_setup(uint eth_num, uint phyaddr) ++{ ++ uint16 tmp; ++ ++ NET_TRACE(("%s enter\n", __FUNCTION__)); ++ ++ phy5461_ge_init(eth_num, phyaddr); ++ ++ /* copper regs */ ++ /* remove power down */ ++ phy5461_mod_reg(eth_num, phyaddr, PHY_MII_CTRLr_FLAGS, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, 0, MII_CTRL_PD); ++ /* Disable super-isolate */ ++ phy5461_mod_reg(eth_num, phyaddr, PHY_MII_POWER_CTRLr_FLAGS, PHY_MII_POWER_CTRLr_BANK, PHY_MII_POWER_CTRLr_ADDR, 0, 1U<<5); ++ /* Enable extended packet length */ ++ phy5461_mod_reg(eth_num, phyaddr, PHY_MII_AUX_CTRLr_FLAGS, PHY_MII_AUX_CTRLr_BANK, PHY_MII_AUX_CTRLr_ADDR, 0x4000, 0x4000); ++ ++ /* Configure interface to MAC */ ++ phy5461_rd_reg(eth_num, phyaddr, PHY_1000X_MII_CTRLr_FLAGS, PHY_1000X_MII_CTRLr_BANK, PHY_1000X_MII_CTRLr_ADDR, &tmp); ++ /* phy5461_ge_init has reset the phy, powering down the unstrapped interface */ ++ /* make sure enabled interfaces are powered up */ ++ /* SGMII (passthrough fiber) or GMII fiber regs */ ++ tmp &= ~MII_CTRL_PD; /* remove power down */ ++ /* ++ * Enable SGMII autonegotiation on the switch side so that the ++ * link status changes are reflected in the switch. ++ * On Bradley devices, LAG failover feature depends on the SerDes ++ * link staus to activate failover recovery. ++ */ ++ tmp |= MII_CTRL_AE; ++ phy5461_wr_reg(eth_num, phyaddr, PHY_1000X_MII_CTRLr_FLAGS, PHY_1000X_MII_CTRLr_BANK, PHY_1000X_MII_CTRLr_ADDR, &tmp); ++ ++ return; ++} ++ ++ ++/* ++ * Function: ++ * phy5461_init ++ * Purpose: ++ * Initialize xgxs6 phys ++ * Parameters: ++ * eth_num - ethernet data ++ * phyaddr - physical address ++ * Returns: ++ * 0 ++ */ ++int ++phy5461_init(uint eth_num, uint phyaddr) ++{ ++ uint16 phyid0, phyid1; ++ ++ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); ++ ++ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_PHY_ID0r_FLAGS, PHY_MII_PHY_ID0r_BANK, PHY_MII_PHY_ID0r_ADDR, &phyid0); ++ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_PHY_ID1r_FLAGS, PHY_MII_PHY_ID1r_BANK, PHY_MII_PHY_ID1r_ADDR, &phyid1); ++ ++ printf("%s Phy ChipID: 0x%04x:0x%04x\n", __FUNCTION__, phyid1, phyid0); ++ ++ phy5461_reset_setup(eth_num, phyaddr); ++ ++ return 0; ++} ++ ++ ++/* ++ * Function: ++ * phy5461_link_get ++ * Purpose: ++ * Determine the current link up/down status ++ * Parameters: ++ * unit - StrataSwitch unit #. ++ * port - StrataSwitch port #. ++ * link - (OUT) Boolean, true indicates link established. ++ * Returns: ++ * SOC_E_XXX ++ * Notes: ++ * No synchronization performed at this level. ++ */ ++int ++phy5461_link_get(uint eth_num, uint phyaddr, int *link) ++{ ++ uint16 mii_ctrl, mii_stat; ++ uint32 wait; ++ ++ *link = FALSE; /* Default */ ++ ++ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_STATr_FLAGS, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &mii_stat); ++ /* the first read of status register will not show link up, second read will show link up */ ++ if (!(mii_stat & MII_STAT_LA) ) { ++ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_STATr_FLAGS, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &mii_stat); ++ } ++ ++ if (!(mii_stat & MII_STAT_LA) || (mii_stat == 0xffff)) { ++ /* mii_stat == 0xffff check is to handle removable PHY daughter cards */ ++ return SOC_E_NONE; ++ } ++ ++ /* Link appears to be up; we are done if autoneg is off. */ ++ ++ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_FLAGS, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); ++ ++ if (!(mii_ctrl & MII_CTRL_AE)) { ++ *link = TRUE; ++ return SOC_E_NONE; ++ } ++ ++ /* ++ * If link appears to be up but autonegotiation is still in ++ * progress, wait for it to complete. For BCM5228, autoneg can ++ * still be busy up to about 200 usec after link is indicated. Also ++ * continue to check link state in case it goes back down. ++ */ ++ for (wait=0; wait<50000; wait++) { ++ ++ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_STATr_FLAGS, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &mii_stat); ++ ++ if (!(mii_stat & MII_STAT_LA)) { ++ /* link is down */ ++ return SOC_E_NONE; ++ } ++ ++ if (mii_stat & MII_STAT_AN_DONE) { ++ /* AutoNegotiation done */ ++ break; ++ } ++ ++ OSL_DELAY(10); ++ } ++ if (wait>=50000) { ++ /* timeout */ ++ return SOC_E_BUSY; ++ } ++ ++ /* Return link state at end of polling */ ++ *link = ((mii_stat & MII_STAT_LA) != 0); ++ ++ return SOC_E_NONE; ++} ++ ++ ++/* ++ * Function: ++ * phy5461_enable_set ++ * Purpose: ++ * Enable/Disable phy ++ * Parameters: ++ * eth_num - ethernet data ++ * phyaddr - physical address ++ * enable - on/off state to set ++ * Returns: ++ * 0 ++ */ ++int ++phy5461_enable_set(uint eth_num, uint phyaddr, int enable) ++{ ++ uint16 power_down; ++ ++ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); ++ ++ power_down = (enable) ? 0 : MII_CTRL_PD; ++ ++ phy5461_mod_reg(eth_num, phyaddr, PHY_MII_CTRLr_FLAGS, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, power_down, MII_CTRL_PD); ++ ++ return SOC_E_NONE; ++} ++ ++ ++#ifdef BCMINTERNAL ++/* ++ * Function: ++ * phy5461_speed_set ++ * Purpose: ++ * Set PHY speed ++ * Parameters: ++ * eth_num - ethernet data ++ * phyaddr - physical address ++ * speed - link speed in Mbps ++ * Returns: ++ * 0 ++ */ ++int ++phy5461_speed_set(uint eth_num, uint phyaddr, int speed) ++{ ++ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); ++ ++ phy5461_ge_speed_set(eth_num, phyaddr, speed); ++ ++ return 0; ++} ++#endif /* BCMINTERNAL */ ++ ++ ++/* ++ * Function: ++ * phy5461_auto_negotiate_gcd (greatest common denominator). ++ * Purpose: ++ * Determine the current greatest common denominator between ++ * two ends of a link ++ * Parameters: ++ * unit - StrataSwitch unit #. ++ * port - StrataSwitch port #. ++ * speed - (OUT) greatest common speed. ++ * duplex - (OUT) greatest common duplex. ++ * link - (OUT) Boolean, true indicates link established. ++ * Returns: ++ * SOC_E_XXX ++ * Notes: ++ * No synchronization performed at this level. ++ */ ++static int ++phy5461_auto_negotiate_gcd(uint eth_num, uint phyaddr, int *speed, int *duplex) ++{ ++ int t_speed, t_duplex; ++ uint16 mii_ana, mii_anp, mii_stat; ++ uint16 mii_gb_stat, mii_esr, mii_gb_ctrl; ++ ++ mii_gb_stat = 0; /* Start off 0 */ ++ mii_gb_ctrl = 0; /* Start off 0 */ ++ ++ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_ANAr_FLAGS, PHY_MII_ANAr_BANK, PHY_MII_ANAr_ADDR, &mii_ana); ++ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_ANPr_FLAGS, PHY_MII_ANPr_BANK, PHY_MII_ANPr_ADDR, &mii_anp); ++ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_STATr_FLAGS, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &mii_stat); ++ ++ if (mii_stat & MII_STAT_ES) { /* Supports extended status */ ++ /* ++ * If the PHY supports extended status, check if it is 1000MB ++ * capable. If it is, check the 1000Base status register to see ++ * if 1000MB negotiated. ++ */ ++ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_ESRr_FLAGS, PHY_MII_ESRr_BANK, PHY_MII_ESRr_ADDR, &mii_esr); ++ ++ if (mii_esr & (MII_ESR_1000_X_FD | MII_ESR_1000_X_HD | ++ MII_ESR_1000_T_FD | MII_ESR_1000_T_HD)) { ++ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_GB_STATr_FLAGS, PHY_MII_GB_STATr_BANK, PHY_MII_GB_STATr_ADDR, &mii_gb_stat); ++ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_GB_CTRLr_FLAGS, PHY_MII_GB_CTRLr_BANK, PHY_MII_GB_CTRLr_ADDR, &mii_gb_ctrl); ++ } ++ } ++ ++ /* ++ * At this point, if we did not see Gig status, one of mii_gb_stat or ++ * mii_gb_ctrl will be 0. This will cause the first 2 cases below to ++ * fail and fall into the default 10/100 cases. ++ */ ++ ++ mii_ana &= mii_anp; ++ ++ if ((mii_gb_ctrl & MII_GB_CTRL_ADV_1000FD) && ++ (mii_gb_stat & MII_GB_STAT_LP_1000FD)) { ++ t_speed = 1000; ++ t_duplex = 1; ++ } else if ((mii_gb_ctrl & MII_GB_CTRL_ADV_1000HD) && ++ (mii_gb_stat & MII_GB_STAT_LP_1000HD)) { ++ t_speed = 1000; ++ t_duplex = 0; ++ } else if (mii_ana & MII_ANA_FD_100) { /* [a] */ ++ t_speed = 100; ++ t_duplex = 1; ++ } else if (mii_ana & MII_ANA_T4) { /* [b] */ ++ t_speed = 100; ++ t_duplex = 0; ++ } else if (mii_ana & MII_ANA_HD_100) { /* [c] */ ++ t_speed = 100; ++ t_duplex = 0; ++ } else if (mii_ana & MII_ANA_FD_10) { /* [d] */ ++ t_speed = 10; ++ t_duplex = 1 ; ++ } else if (mii_ana & MII_ANA_HD_10) { /* [e] */ ++ t_speed = 10; ++ t_duplex = 0; ++ } else { ++ return(SOC_E_FAIL); ++ } ++ ++ if (speed) *speed = t_speed; ++ if (duplex) *duplex = t_duplex; ++ ++ return(SOC_E_NONE); ++} ++ ++ ++/* ++ * Function: ++ * phy5461_speed_get ++ * Purpose: ++ * Get PHY speed ++ * Parameters: ++ * eth_num - ethernet data ++ * phyaddr - physical address ++ * speed - current link speed in Mbps ++ * Returns: ++ * 0 ++ */ ++int ++phy5461_speed_get(uint eth_num, uint phyaddr, int *speed, int *duplex) ++{ ++ int rv; ++ uint16 mii_ctrl, mii_stat; ++ ++ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); ++ ++ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_FLAGS, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); ++ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_STATr_FLAGS, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &mii_stat); ++ ++ *speed = 0; ++ *duplex = 0; ++ if (mii_ctrl & MII_CTRL_AE) { /* Auto-negotiation enabled */ ++ if (!(mii_stat & MII_STAT_AN_DONE)) { /* Auto-neg NOT complete */ ++ rv = SOC_E_NONE; ++ } else { ++ rv = phy5461_auto_negotiate_gcd(eth_num, phyaddr, speed, duplex); ++ } ++ } else { /* Auto-negotiation disabled */ ++ /* ++ * Simply pick up the values we force in CTRL register. ++ */ ++ if (mii_ctrl & MII_CTRL_FD) ++ *duplex = 1; ++ ++ switch(MII_CTRL_SS(mii_ctrl)) { ++ case MII_CTRL_SS_10: ++ *speed = 10; ++ break; ++ case MII_CTRL_SS_100: ++ *speed = 100; ++ break; ++ case MII_CTRL_SS_1000: ++ *speed = 1000; ++ break; ++ default: /* Just pass error back */ ++ return(SOC_E_UNAVAIL); ++ } ++ rv = SOC_E_NONE; ++ } ++ ++ return(rv); ++} ++ ++ ++#ifdef BCMINTERNAL ++int ++phy5461_lb_set(uint eth_num, uint phyaddr, int enable) ++{ ++ uint16 mii_ctrl; ++ ++ /* set reset flag */ ++ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_FLAGS, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); ++ mii_ctrl &= ~MII_CTRL_LE; ++ mii_ctrl |= enable ? MII_CTRL_LE : 0; ++ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_FLAGS, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); ++ ++ return 0; ++} ++ ++ ++void ++phy5461_disp_status(uint eth_num, uint phyaddr) ++{ ++ uint16 tmp0, tmp1, tmp2; ++ int speed, duplex; ++ ++ printf("et%d: %s: phyaddr:%d\n", eth_num, __FUNCTION__, phyaddr); ++ ++ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_FLAGS, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &tmp0); ++ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_STATr_FLAGS, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &tmp1); ++ printf(" MII-Control: 0x%x; MII-Status: 0x%x\n", tmp0, tmp1); ++ ++ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_PHY_ID0r_FLAGS, PHY_MII_PHY_ID0r_BANK, PHY_MII_PHY_ID0r_ADDR, &tmp0); ++ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_PHY_ID1r_FLAGS, PHY_MII_PHY_ID1r_BANK, PHY_MII_PHY_ID1r_ADDR, &tmp1); ++ printf(" Phy ChipID: 0x%04x:0x%04x\n", tmp0, tmp1); ++ ++ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_ANAr_FLAGS, PHY_MII_ANAr_BANK, PHY_MII_ANAr_ADDR, &tmp0); ++ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_ANPr_FLAGS, PHY_MII_ANPr_BANK, PHY_MII_ANPr_ADDR, &tmp1); ++ phy5461_speed_get(eth_num, phyaddr, &speed, &duplex); ++ printf(" AutoNeg Ad: 0x%x; AutoNeg Partner: 0x%x; speed:%d; duplex:%d\n", tmp0, tmp1, speed, duplex); ++ ++ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_GB_CTRLr_FLAGS, PHY_MII_GB_CTRLr_BANK, PHY_MII_GB_CTRLr_ADDR, &tmp0); ++ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_GB_STATr_FLAGS, PHY_MII_GB_STATr_BANK, PHY_MII_GB_STATr_ADDR, &tmp1); ++ printf(" MII GB ctrl: 0x%x; MII GB stat: 0x%x\n", tmp0, tmp1); ++ ++ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_ESRr_FLAGS, PHY_MII_ESRr_BANK, PHY_MII_ESRr_ADDR, &tmp0); ++ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_ECRr_FLAGS, PHY_MII_ECRr_BANK, PHY_MII_ECRr_ADDR, &tmp1); ++ phy5461_rd_reg(eth_num, phyaddr, 0x00, 0x0000, 0x11, &tmp2); ++ printf(" IEEE Ext stat: 0x%x; PHY Ext ctrl: 0x%x; PHY Ext stat: 0x%x\n", tmp0, tmp1, tmp2); ++ ++ phy5461_rd_reg(eth_num, phyaddr, PHY_MODE_CTRLr_FLAGS, PHY_MODE_CTRLr_BANK, PHY_MODE_CTRLr_ADDR, &tmp0); ++ printf(" Mode Control (Addr 1c shadow 1f): 0x%x\n", tmp0); ++ ++ phy5461_rd_reg(eth_num, phyaddr, PHY_1000X_MII_CTRLr_FLAGS, PHY_1000X_MII_CTRLr_BANK, PHY_1000X_MII_CTRLr_ADDR, &tmp0); ++ phy5461_rd_reg(eth_num, phyaddr, PHY_1000X_MII_CTRLr_FLAGS, PHY_1000X_MII_CTRLr_BANK, 0x01, &tmp1); ++ printf(" 1000-x MII ctrl: 0x%x; 1000-x MII stat: 0x%x\n", tmp0, tmp1); ++ ++ phy5461_rd_reg(eth_num, phyaddr, PHY_1000X_MII_CTRLr_FLAGS, PHY_1000X_MII_CTRLr_BANK, 0x04, &tmp0); ++ phy5461_rd_reg(eth_num, phyaddr, PHY_1000X_MII_CTRLr_FLAGS, PHY_1000X_MII_CTRLr_BANK, 0x05, &tmp1); ++ printf(" 1000-x AutoNeg Ad: 0x%x; 1000-x AutoNeg Partner: 0x%x\n", tmp0, tmp1); ++ ++} ++#endif /* BCMINTERNAL */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_phy5481.c b/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_phy5481.c +--- a/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_phy5481.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_phy5481.c 2017-11-09 17:53:44.028289000 +0800 +@@ -0,0 +1,728 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ * ++ * These routines provide access to the external phy ++ * ++ */ ++ ++/* ---- Include Files ---------------------------------------------------- */ ++#include ++#include ++#include "../../../mdio/iproc_mdio.h" ++#include "bcmiproc_phy.h" ++#include "bcmiproc_phy5481.h" ++ ++/* ---- External Variable Declarations ----------------------------------- */ ++/* ---- External Function Prototypes ------------------------------------- */ ++/* ---- Public Variables ------------------------------------------------- */ ++/* ---- Private Constants and Types -------------------------------------- */ ++/* ---- Private Variables ------------------------------------------------ */ ++ ++/* debug/trace */ ++//#define BCMDBG ++//#define BCMDBG_ERR ++#ifdef BCMDBG ++#define NET_ERROR(args) printf args ++#define NET_TRACE(args) printf args ++#elif defined(BCMDBG_ERR) ++#define NET_ERROR(args) printf args ++#define NET_TRACE(args) ++#else ++#define NET_ERROR(args) ++#define NET_TRACE(args) ++#endif /* BCMDBG */ ++#define NET_REG_TRACE(args) ++ ++ ++#ifndef ASSERT ++#define ASSERT(exp) ++#endif ++ ++ ++/* ==== Public Functions ================================================= */ ++ ++int ++phy5481_wr_reg(uint eth_num, uint phyaddr, uint16 reg_bank, ++ uint8 reg_addr, uint16 *data) ++{ ++ int rv = SOC_E_NONE; ++ uint16 wr_data=*data; ++ ++ NET_TRACE(("%s enter\n", __FUNCTION__)); ++ ++ NET_REG_TRACE(("%s going to write phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", ++ __FUNCTION__, phyaddr, reg_bank, reg_addr, wr_data)); ++ ++ switch(reg_addr) { ++ /* Map shadow registers */ ++ case 0x18: ++ if (reg_bank <= 0x0007) { ++ if (reg_bank == 0x0007) { ++ wr_data |= 0x8000; ++ } ++ wr_data = (wr_data & ~(0x0007)) | reg_bank; ++ } else { ++ rv = SOC_E_PARAM; ++ } ++ break; ++ case 0x1C: ++ if (reg_bank <= 0x000F) { ++ wr_data = 0x8000 | (reg_bank << 10) | (wr_data & 0x03FF); ++ } else { ++ rv = SOC_E_PARAM; ++ } ++ break; ++ default: ++ if (reg_addr > 0x001e) { ++ rv = SOC_E_PARAM; ++ } ++ break; ++ } ++ ++ if (SOC_SUCCESS(rv)) { ++ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, wr_data); ++ } ++ ++ return rv; ++} ++ ++ ++int ++phy5481_rd_reg(uint eth_num, uint phyaddr, uint16 reg_bank, ++ uint8 reg_addr, uint16 *data) ++{ ++ int rv = SOC_E_NONE; ++ ++ NET_TRACE(("%s enter\n", __FUNCTION__)); ++ ++ NET_REG_TRACE(("%s going to read phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x)\n", ++ __FUNCTION__, phyaddr, reg_bank, reg_addr)); ++ ++ switch(reg_addr) { ++ /* Map shadow registers */ ++ case 0x18: ++ if (reg_bank <= 0x0007) { ++ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, (reg_bank << 12) | 0x7); ++ } else { ++ rv = SOC_E_PARAM; ++ } ++ break; ++ case 0x1C: ++ if (reg_bank <= 0x00F) { ++ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, (reg_bank << 10)); ++ } else { ++ rv = SOC_E_PARAM; ++ } ++ break; ++ default: ++ if (reg_addr > 0x001e) { ++ rv = SOC_E_PARAM; ++ } ++ break; ++ } ++ ++ if (SOC_SUCCESS(rv)) { ++ iproc_mii_read(MII_DEV_EXT, phyaddr, reg_addr, data); ++ NET_REG_TRACE(("%s rd phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", ++ __FUNCTION__, phyaddr, reg_bank, reg_addr, *data)); ++ } ++ ++ return rv; ++} ++ ++ ++int ++phy5481_mod_reg(uint eth_num, uint phyaddr, uint16 reg_bank, ++ uint8 reg_addr, uint16 data, uint16 mask) ++{ ++ int rv = SOC_E_NONE; ++ uint16 org_data, rd_data; ++ ++ NET_TRACE(("%s enter\n", __FUNCTION__)); ++ ++ NET_REG_TRACE(("%s going to modify phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x) mask(0x%x)\n", ++ __FUNCTION__, phyaddr, reg_bank, reg_addr, data, mask)); ++ ++ switch(reg_addr) { ++ /* Map shadow registers */ ++ case 0x18: ++ if (reg_bank <= 0x0007) { ++ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, (reg_bank << 12) | 0x7); ++ if (reg_bank == 0x0007) { ++ data |= 0x8000; ++ mask |= 0x8000; ++ } ++ mask &= ~(0x0007); ++ } else { ++ rv = SOC_E_PARAM; ++ } ++ break; ++ case 0x1C: ++ if (reg_bank <= 0x001F) { ++ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, (reg_bank << 10)); ++ data |= 0x8000; ++ mask |= 0x8000; ++ mask &= ~(0x1F << 10); ++ } else { ++ rv = SOC_E_PARAM; ++ } ++ break; ++ default: ++ if (reg_addr > 0x001e) { ++ rv = SOC_E_PARAM; ++ } ++ break; ++ } ++ ++ if (SOC_SUCCESS(rv)) { ++ iproc_mii_read(MII_DEV_EXT, phyaddr, reg_addr, &rd_data); ++ NET_REG_TRACE(("%s rd phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", ++ __FUNCTION__, phyaddr, reg_bank, reg_addr, rd_data)); ++ org_data = rd_data; ++ rd_data &= ~(mask); ++ rd_data |= data; ++ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, rd_data); ++ NET_REG_TRACE(("%s wrt phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", ++ __FUNCTION__, phyaddr, reg_bank, reg_addr, rd_data)); ++ } ++ ++ return rv; ++} ++ ++void ++phy5481_ge_reset(uint eth_num, uint phyaddr) ++{ ++ uint16 ctrl; ++ ++ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); ++ ++ /* set reset flag */ ++ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &ctrl); ++ ctrl |= MII_CTRL_RESET; ++ phy5481_wr_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &ctrl); ++ ++ SPINWAIT( (!phy5481_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &ctrl) ++ && (ctrl & MII_CTRL_RESET)), 100000); ++ /* check if out of reset */ ++ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &ctrl); ++ if (ctrl & MII_CTRL_RESET) { ++ /* timeout */ ++ NET_ERROR(("et%d: %s reset not complete\n", eth_num, __FUNCTION__)); ++ } else { ++ NET_ERROR(("et%d: %s reset complete\n", eth_num, __FUNCTION__)); ++ } ++ ++ return; ++} ++ ++ ++/* ++ * Function: ++ * phy5481_ge_init ++ * Purpose: ++ * Initialize the PHY (MII mode) to a known good state. ++ * Parameters: ++ * unit - StrataSwitch unit #. ++ * port - StrataSwitch port #. ++ * Returns: ++ * SOC_E_XXX ++ ++ * Notes: ++ * No synchronization performed at this level. ++ */ ++int ++phy5481_ge_init(uint eth_num, uint phyaddr) ++{ ++ uint16 mii_ana, mii_ctrl, mii_gb_ctrl; ++ ++ /* Reset PHY */ ++ phy5481_ge_reset(eth_num, phyaddr); ++ ++ /* set advertized bits */ ++ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_ANAr_BANK, PHY_MII_ANAr_ADDR, &mii_ana); ++ mii_ana |= MII_ANA_FD_100 | MII_ANA_FD_10; ++ mii_ana |= MII_ANA_HD_100 | MII_ANA_HD_10; ++ phy5481_wr_reg(eth_num, phyaddr, PHY_MII_ANAr_BANK, PHY_MII_ANAr_ADDR, &mii_ana); ++ ++ ++ mii_ctrl = MII_CTRL_FD | MII_CTRL_SS_1000 | MII_CTRL_AE | MII_CTRL_RAN; ++ mii_gb_ctrl = MII_GB_CTRL_ADV_1000FD | MII_GB_CTRL_PT; ++ ++ phy5481_wr_reg(eth_num, phyaddr, PHY_MII_GB_CTRLr_BANK, PHY_MII_GB_CTRLr_ADDR, &mii_gb_ctrl); ++ phy5481_wr_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); ++ ++ ++ return SOC_E_NONE; ++} ++ ++ ++#ifdef BCMINTERNAL ++/* ++ * Function: ++ * phy5481_ge_speed_set ++ * Purpose: ++ * Set the current operating speed (forced). ++ * Parameters: ++ * unit - StrataSwitch unit #. ++ * port - StrataSwitch port #. ++ * duplex - (OUT) Boolean, true indicates full duplex, false ++ * indicates half. ++ * Returns: ++ * SOC_E_XXX ++ * Notes: ++ * No synchronization performed at this level. Autonegotiation is ++ * not manipulated. ++ */ ++int ++phy5481_ge_speed_set(uint eth_num, uint phyaddr, int speed) ++{ ++ uint16 mii_ctrl; ++ ++ if (speed == 0) { ++ return SOC_E_NONE; ++ } ++ ++ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); ++ ++ mii_ctrl &= ~(MII_CTRL_SS_LSB | MII_CTRL_SS_MSB); ++ switch(speed) { ++ case 10: ++ mii_ctrl |= MII_CTRL_SS_10; ++ break; ++ case 100: ++ mii_ctrl |= MII_CTRL_SS_100; ++ break; ++ case 1000: ++ mii_ctrl |= MII_CTRL_SS_1000; ++ break; ++ default: ++ return SOC_E_CONFIG; ++ } ++ ++ phy5481_wr_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); ++ ++ return SOC_E_NONE; ++} ++#endif /* BCMINTERNAL */ ++ ++void ++phy5481_reset_setup(uint eth_num, uint phyaddr) ++{ ++ ++ NET_TRACE(("%s enter\n", __FUNCTION__)); ++ ++ phy5481_ge_init(eth_num, phyaddr); ++ ++ /* copper regs */ ++ /* remove power down */ ++ phy5481_mod_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, 0, MII_CTRL_PD); ++ /* Disable super-isolate */ ++ phy5481_mod_reg(eth_num, phyaddr, PHY_MII_POWER_CTRLr_BANK, PHY_MII_POWER_CTRLr_ADDR, 0, PHY5481_SUPER_ISOLATE_MODE); ++ /* Enable extended packet length */ ++ phy5481_mod_reg(eth_num, phyaddr, PHY_MII_AUX_CTRLr_BANK, PHY_MII_AUX_CTRLr_ADDR, 0x4000, 0x4000); ++ ++ return; ++} ++ ++ ++/* ++ * Function: ++ * phy5481_init ++ * Purpose: ++ * Initialize xgxs6 phys ++ * Parameters: ++ * eth_num - ethernet data ++ * phyaddr - physical address ++ * Returns: ++ * 0 ++ */ ++int ++phy5481_init(uint eth_num, uint phyaddr) ++{ ++ uint16 phyid0, phyid1; ++ ++ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); ++ ++ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_PHY_ID0r_BANK, PHY_MII_PHY_ID0r_ADDR, &phyid0); ++ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_PHY_ID1r_BANK, PHY_MII_PHY_ID1r_ADDR, &phyid1); ++ ++ printf("%s phyaddr(0x%x) Phy ChipID: 0x%04x:0x%04x\n", __FUNCTION__, phyaddr, phyid1, phyid0); ++ ++ phy5481_reset_setup(eth_num, phyaddr); ++ ++ return 0; ++} ++ ++ ++/* ++ * Function: ++ * phy5481_link_get ++ * Purpose: ++ * Determine the current link up/down status ++ * Parameters: ++ * unit - StrataSwitch unit #. ++ * port - StrataSwitch port #. ++ * link - (OUT) Boolean, true indicates link established. ++ * Returns: ++ * SOC_E_XXX ++ * Notes: ++ * No synchronization performed at this level. ++ */ ++int ++phy5481_link_get(uint eth_num, uint phyaddr, int *link) ++{ ++ uint16 mii_ctrl, mii_stat; ++ uint32 wait; ++ ++ *link = FALSE; /* Default */ ++ ++ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &mii_stat); ++ /* the first read of status register will not show link up, second read will show link up */ ++ if (!(mii_stat & MII_STAT_LA) ) { ++ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &mii_stat); ++ } ++ ++ if (!(mii_stat & MII_STAT_LA) || (mii_stat == 0xffff)) { ++ /* mii_stat == 0xffff check is to handle removable PHY daughter cards */ ++ return SOC_E_NONE; ++ } ++ ++ /* Link appears to be up; we are done if autoneg is off. */ ++ ++ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); ++ ++ if (!(mii_ctrl & MII_CTRL_AE)) { ++ *link = TRUE; ++ return SOC_E_NONE; ++ } ++ ++ /* ++ * If link appears to be up but autonegotiation is still in ++ * progress, wait for it to complete. For BCM5228, autoneg can ++ * still be busy up to about 200 usec after link is indicated. Also ++ * continue to check link state in case it goes back down. ++ * wait 500ms (500000us/10us = 50000 ) ++ */ ++ for (wait=0; wait<50000; wait++) { ++ ++ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &mii_stat); ++ ++ if (!(mii_stat & MII_STAT_LA)) { ++ /* link is down */ ++ return SOC_E_NONE; ++ } ++ ++ if (mii_stat & MII_STAT_AN_DONE) { ++ /* AutoNegotiation done */ ++ break; ++ } ++ ++ OSL_DELAY(10); ++ } ++ if (wait>=50000) { ++ /* timeout */ ++ return SOC_E_BUSY; ++ } ++ ++ /* Return link state at end of polling */ ++ *link = ((mii_stat & MII_STAT_LA) != 0); ++ ++ return SOC_E_NONE; ++} ++ ++/* ++ * Function: ++ * phy5481_enable_set ++ * Purpose: ++ * Enable/Disable phy ++ * Parameters: ++ * eth_num - ethernet data ++ * phyaddr - physical address ++ * enable - on/off state to set ++ * Returns: ++ * 0 ++ */ ++int ++phy5481_enable_set(uint eth_num, uint phyaddr, int enable) ++{ ++ uint16 power_down; ++ ++ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); ++ ++ power_down = (enable) ? 0 : MII_CTRL_PD; ++ ++ phy5481_mod_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, power_down, MII_CTRL_PD); ++ ++ return SOC_E_NONE; ++} ++ ++ ++#ifdef BCMINTERNAL ++ ++/* ++ * Function: ++ * phy5481_speed_set ++ * Purpose: ++ * Set PHY speed ++ * Parameters: ++ * eth_num - ethernet data ++ * phyaddr - physical address ++ * speed - link speed in Mbps ++ * Returns: ++ * 0 ++ */ ++int ++phy5481_speed_set(uint eth_num, uint phyaddr, int speed) ++{ ++ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); ++ ++ phy5481_ge_speed_set(eth_num, phyaddr, speed); ++ ++ return 0; ++} ++#endif /* BCMINTERNAL */ ++ ++ ++/* ++ * Function: ++ * phy5481_auto_negotiate_gcd (greatest common denominator). ++ * Purpose: ++ * Determine the current greatest common denominator between ++ * two ends of a link ++ * Parameters: ++ * unit - StrataSwitch unit #. ++ * port - StrataSwitch port #. ++ * speed - (OUT) greatest common speed. ++ * duplex - (OUT) greatest common duplex. ++ * link - (OUT) Boolean, true indicates link established. ++ * Returns: ++ * SOC_E_XXX ++ * Notes: ++ * No synchronization performed at this level. ++ */ ++static int ++phy5481_auto_negotiate_gcd(uint eth_num, uint phyaddr, int *speed, int *duplex) ++{ ++ int t_speed, t_duplex; ++ uint16 mii_ana, mii_anp, mii_stat; ++ uint16 mii_gb_stat, mii_esr, mii_gb_ctrl; ++ ++ mii_gb_stat = 0; /* Start off 0 */ ++ mii_gb_ctrl = 0; /* Start off 0 */ ++ ++ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_ANAr_BANK, PHY_MII_ANAr_ADDR, &mii_ana); ++ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_ANPr_BANK, PHY_MII_ANPr_ADDR, &mii_anp); ++ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &mii_stat); ++ ++ if (mii_stat & MII_STAT_ES) { /* Supports extended status */ ++ /* ++ * If the PHY supports extended status, check if it is 1000MB ++ * capable. If it is, check the 1000Base status register to see ++ * if 1000MB negotiated. ++ */ ++ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_ESRr_BANK, PHY_MII_ESRr_ADDR, &mii_esr); ++ ++ if (mii_esr & (MII_ESR_1000_X_FD | MII_ESR_1000_X_HD | ++ MII_ESR_1000_T_FD | MII_ESR_1000_T_HD)) { ++ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_GB_STATr_BANK, PHY_MII_GB_STATr_ADDR, &mii_gb_stat); ++ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_GB_CTRLr_BANK, PHY_MII_GB_CTRLr_ADDR, &mii_gb_ctrl); ++ } ++ } ++ ++ /* ++ * At this point, if we did not see Gig status, one of mii_gb_stat or ++ * mii_gb_ctrl will be 0. This will cause the first 2 cases below to ++ * fail and fall into the default 10/100 cases. ++ */ ++ ++ mii_ana &= mii_anp; ++ ++ if ((mii_gb_ctrl & MII_GB_CTRL_ADV_1000FD) && ++ (mii_gb_stat & MII_GB_STAT_LP_1000FD)) { ++ t_speed = 1000; ++ t_duplex = 1; ++ } else if ((mii_gb_ctrl & MII_GB_CTRL_ADV_1000HD) && ++ (mii_gb_stat & MII_GB_STAT_LP_1000HD)) { ++ t_speed = 1000; ++ t_duplex = 0; ++ } else if (mii_ana & MII_ANA_FD_100) { /* [a] */ ++ t_speed = 100; ++ t_duplex = 1; ++ } else if (mii_ana & MII_ANA_T4) { /* [b] */ ++ t_speed = 100; ++ t_duplex = 0; ++ } else if (mii_ana & MII_ANA_HD_100) { /* [c] */ ++ t_speed = 100; ++ t_duplex = 0; ++ } else if (mii_ana & MII_ANA_FD_10) { /* [d] */ ++ t_speed = 10; ++ t_duplex = 1 ; ++ } else if (mii_ana & MII_ANA_HD_10) { /* [e] */ ++ t_speed = 10; ++ t_duplex = 0; ++ } else { ++ return(SOC_E_FAIL); ++ } ++ ++ if (speed) *speed = t_speed; ++ if (duplex) *duplex = t_duplex; ++ ++ return(SOC_E_NONE); ++} ++ ++ ++/* ++ * Function: ++ * phy5481_speed_get ++ * Purpose: ++ * Get PHY speed ++ * Parameters: ++ * eth_num - ethernet data ++ * phyaddr - physical address ++ * speed - current link speed in Mbps ++ * Returns: ++ * 0 ++ */ ++int ++phy5481_speed_get(uint eth_num, uint phyaddr, int *speed, int *duplex) ++{ ++ int rv; ++ uint16 mii_ctrl, mii_stat; ++ ++ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); ++ ++ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); ++ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &mii_stat); ++ ++ *speed = 0; ++ *duplex = 0; ++ if (mii_ctrl & MII_CTRL_AE) { /* Auto-negotiation enabled */ ++ if (!(mii_stat & MII_STAT_AN_DONE)) { /* Auto-neg NOT complete */ ++ rv = SOC_E_NONE; ++ } else { ++ rv = phy5481_auto_negotiate_gcd(eth_num, phyaddr, speed, duplex); ++ } ++ } else { /* Auto-negotiation disabled */ ++ /* ++ * Simply pick up the values we force in CTRL register. ++ */ ++ if (mii_ctrl & MII_CTRL_FD) ++ *duplex = 1; ++ ++ switch(MII_CTRL_SS(mii_ctrl)) { ++ case MII_CTRL_SS_10: ++ *speed = 10; ++ break; ++ case MII_CTRL_SS_100: ++ *speed = 100; ++ break; ++ case MII_CTRL_SS_1000: ++ *speed = 1000; ++ break; ++ default: /* Just pass error back */ ++ return(SOC_E_UNAVAIL); ++ } ++ rv = SOC_E_NONE; ++ } ++ ++ return(rv); ++} ++ ++ ++#ifdef BCMINTERNAL ++int ++phy5481_lb_set(uint eth_num, uint phyaddr, int enable) ++{ ++ uint16 mii_ctrl; ++ ++ /* set reset flag */ ++ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); ++ mii_ctrl &= ~MII_CTRL_LE; ++ mii_ctrl |= enable ? MII_CTRL_LE : 0; ++ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); ++ ++ return 0; ++} ++#endif /* BCMINTERNAL */ ++ ++ ++#ifdef BCMINTERNAL ++void ++phy5481_disp_status(uint eth_num, uint phyaddr) ++{ ++ uint16 tmp0, tmp1, tmp2; ++ int speed, duplex; ++ ++ printf("et%d: %s: phyaddr:%d\n", eth_num, __FUNCTION__, phyaddr); ++ ++ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &tmp0); ++ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &tmp1); ++ printf(" MII-Control: 0x%x; MII-Status: 0x%x\n", tmp0, tmp1); ++ ++ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_PHY_ID0r_BANK, PHY_MII_PHY_ID0r_ADDR, &tmp0); ++ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_PHY_ID1r_BANK, PHY_MII_PHY_ID1r_ADDR, &tmp1); ++ printf(" Phy ChipID: 0x%04x:0x%04x\n", tmp0, tmp1); ++ ++ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_ANAr_BANK, PHY_MII_ANAr_ADDR, &tmp0); ++ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_ANPr_BANK, PHY_MII_ANPr_ADDR, &tmp1); ++ phy5481_speed_get(eth_num, phyaddr, &speed, &duplex); ++ printf(" AutoNeg Ad: 0x%x; AutoNeg Partner: 0x%x; speed:%d; duplex:%d\n", tmp0, tmp1, speed, duplex); ++ ++ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_ESRr_BANK, PHY_MII_ESRr_ADDR, &tmp0); ++ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_ECRr_BANK, PHY_MII_ECRr_ADDR, &tmp1); ++ phy5481_rd_reg(eth_num, phyaddr, 0x0000, 0x11, &tmp2); ++ printf(" Reg0x0f: 0x%x; 100Base-X AUX ctrl: 0x%x; 100Base-X AUX stat: 0x%x\n", tmp0, tmp1, tmp2); ++ ++ phy5481_rd_reg(eth_num, phyaddr, 0x0000, 0x12, &tmp0); ++ phy5481_rd_reg(eth_num, phyaddr, 0x0000, 0x13, &tmp1); ++ phy5481_rd_reg(eth_num, phyaddr, 0x0000, 0x14, &tmp2); ++ printf(" 100Base-X RCV ERR: 0x%x; 100Base-X FALSE CARRIER: 0x%x; 100Base-X DISCON: 0x%x\n", tmp0, tmp1, tmp2); ++} ++#endif /* BCMINTERNAL */ ++ ++ ++#ifdef BCMINTERNAL ++void ++phy5481_chk_err(uint eth_num, uint phyaddr) ++{ ++ uint16 tmp0; ++ ++ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &tmp0); ++ if (!(tmp0 & MII_STAT_LA)) ++ printf("ERROR: reg 0x01 (LINK down): 0x%x\n", tmp0); ++ if (tmp0 & (MII_STAT_JBBR|MII_STAT_RF)) { ++ printf("ERROR: reg 0x01: 0x%x\n", tmp0); ++ } ++ ++ phy5481_rd_reg(eth_num, phyaddr, 0, 0x11, &tmp0); ++ if (!(tmp0 & 0x100)) { ++ printf("ERROR: reg 0x11 (LINK down): 0x%x\n", tmp0); ++ } ++ if (tmp0 & 0x8bf) { ++ printf("ERROR: reg 0x11: 0x%x\n", tmp0); ++ } ++ ++ phy5481_rd_reg(eth_num, phyaddr, 0, 0x12, &tmp0); ++ if (tmp0) { ++ printf("ERROR: reg 0x12 (RCV ERR CNT): 0x%x\n", tmp0); ++ } ++ ++ phy5481_rd_reg(eth_num, phyaddr, 0, 0x13, &tmp0); ++ if (tmp0) { ++ printf("ERROR: reg 0x13 (FALSE CARRIER CNT): 0x%x\n", tmp0); ++ } ++ ++ phy5481_rd_reg(eth_num, phyaddr, 0, 0x14, &tmp0); ++ if (tmp0 & 0xc000) { ++ printf("ERROR: reg 0x14: 0x%x\n", tmp0); ++ } ++ ++ phy5481_rd_reg(eth_num, phyaddr, 0, 0x19, &tmp0); ++ if (!(tmp0 & 0x4)) { ++ printf("ERROR: reg 0x19 (LINK down): 0x%x\n", tmp0); ++ } ++ if (tmp0 & 0xc0) { ++ printf("ERROR: reg 0x19: 0x%x\n", tmp0); ++ } ++} ++#endif /* BCMINTERNAL */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_serdes.c b/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_serdes.c +--- a/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_serdes.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_serdes.c 2017-11-09 17:53:44.029293000 +0800 +@@ -0,0 +1,879 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ * ++ * These routines provide access to the serdes ++ * ++ */ ++ ++/* ---- Include Files ---------------------------------------------------- */ ++#include ++#include ++#include "bcmiproc_serdes.h" ++#include "bcmiproc_serdes_def.h" ++#include "../../../mdio/iproc_mdio.h" ++ ++/* ---- External Variable Declarations ----------------------------------- */ ++/* ---- External Function Prototypes ------------------------------------- */ ++/* ---- Public Variables ------------------------------------------------- */ ++/* ---- Private Constants and Types -------------------------------------- */ ++/* ---- Private Variables ------------------------------------------------ */ ++ ++/* debug/trace */ ++//#define BCMDBG ++//#define BCMDBG_ERR ++#ifdef BCMDBG ++#define NET_ERROR(args) printf args ++#define NET_TRACE(args) printf args ++#elif defined(BCMDBG_ERR) ++#define NET_ERROR(args) printf args ++#define NET_TRACE(args) ++#else ++#define NET_ERROR(args) ++#define NET_TRACE(args) ++#endif /* BCMDBG */ ++#define NET_REG_TRACE(args) ++ ++ ++#ifndef ASSERT ++#define ASSERT(exp) ++#endif ++ ++ ++#if defined(CONFIG_MACH_SB2) ++/* CL22 register access for VIPERCORE in Saber2 */ ++#define PHY_AER_REG_ADDR_AER(_addr) (((_addr) >> 16) & 0x0000FFFF) ++#define PHY_AER_REG_ADDR_BLK(_addr) (((_addr) & 0x0000FFF0)) ++#define PHY_AER_REG_ADDR_REGAD(_addr) ((((_addr) & 0x00008000) >> 11) | \ ++ ((_addr) & 0x0000000F)) ++#endif ++ ++/* ==== Public Functions ================================================= */ ++ ++void ++serdes_set_blk(uint eth_num, uint phyaddr, uint blk) ++{ ++ uint16 blkaddr; ++ uint16 destblk = (uint16)blk; ++ ++ NET_TRACE(("%s enter\n", __FUNCTION__)); ++ ++ NET_REG_TRACE(("%s phyaddr(0x%x) blk(0x%x)\n", ++ __FUNCTION__, phyaddr, blk)); ++ ++ /* check if need to update blk addr */ ++ iproc_mii_read(MII_DEV_LOCAL, phyaddr, PHY_REG_BLK_ADDR, &blkaddr); ++ if (blkaddr!=destblk) { ++ /* write block address */ ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, PHY_REG_BLK_ADDR, destblk); ++ } ++} ++ ++ ++void ++serdes_wr_reg(uint eth_num, uint phyaddr, uint reg, uint data) ++{ ++ uint16 tmpdata=(uint16)data; ++#if defined(CONFIG_MACH_SB2) ++ uint16 phy_reg_aer = 0, phy_reg_blk = 0, phy_reg_addr = 0; ++ ++ phy_reg_aer = PHY_AER_REG_ADDR_AER(reg); /* upper 16 bits */ ++ phy_reg_blk = PHY_AER_REG_ADDR_BLK(reg); /* 12 bits mask=0xfff0 */ ++ phy_reg_addr = PHY_AER_REG_ADDR_REGAD(reg); /* 5 bits {15,3,2,1,0} */ ++ ++ if (phy_reg_aer != 0) { ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0xffd0); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001e, phy_reg_aer); ++ } ++ ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, phy_reg_blk); /* Map block */ ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, phy_reg_addr, tmpdata); /* write register */ ++ ++ if (phy_reg_aer != 0) { ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0xffd0); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001e, 0x0); ++ } ++#else ++ uint blk = reg&0x7ff0; ++ uint off = reg&0x000f; ++ ++ NET_TRACE(("%s enter\n", __FUNCTION__)); ++ ++ if (reg&0x8000) ++ off|=0x10; ++ ++ /* set block address */ ++ serdes_set_blk(eth_num, phyaddr, blk); ++ ++ NET_REG_TRACE(("%s wrt phyaddr(0x%x) reg(0x%x) data(0x%x)\n", ++ __FUNCTION__, phyaddr, reg, tmpdata)); ++ //printf("%s wrt phyaddr(0x%x) reg(0x%x) data(0x%x)\n", ++ // __FUNCTION__, phyaddr, reg, tmpdata); ++ /* write register */ ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, off, tmpdata); ++#endif ++} ++ ++ ++uint16 ++serdes_rd_reg(uint eth_num, uint phyaddr, uint reg) ++{ ++ uint16 data; ++#if defined(CONFIG_MACH_SB2) ++ uint16 phy_reg_aer = 0, phy_reg_blk = 0, phy_reg_addr = 0; ++ ++ phy_reg_aer = PHY_AER_REG_ADDR_AER(reg); /* upper 16 bits */ ++ phy_reg_blk = PHY_AER_REG_ADDR_BLK(reg); /* 12 bits mask=0xfff0 */ ++ phy_reg_addr = PHY_AER_REG_ADDR_REGAD(reg); /* 5 bits {15,3,2,1,0} */ ++ ++ if (phy_reg_aer != 0) { ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0xffd0); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001e, phy_reg_aer); ++ } ++ ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, phy_reg_blk); /* Map block */ ++ iproc_mii_read(MII_DEV_LOCAL, phyaddr, phy_reg_addr, &data); /* read register */ ++ ++ if (phy_reg_aer != 0) { ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0xffd0); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001e, 0x0); ++ } ++#else ++ uint blk = reg&0x7ff0; ++ uint off = reg&0x000f; ++ ++ NET_TRACE(("%s enter\n", __FUNCTION__)); ++ ++ if (reg&0x8000) ++ off|=0x10; ++ ++ /* set block address */ ++ serdes_set_blk(eth_num, phyaddr, blk); ++ ++ /* read register */ ++ iproc_mii_read(MII_DEV_LOCAL, phyaddr, off, &data); ++ NET_REG_TRACE(("%s rd phyaddr(0x%x) reg(0x%x) data(0x%x)\n", ++ __FUNCTION__, phyaddr, reg, data)); ++ //printf("%s rd phyaddr(0x%x) reg(0x%x) data(0x%x)\n", ++ // __FUNCTION__, phyaddr, reg, data); ++#endif ++ ++ return data; ++} ++ ++ ++uint16 ++serdes_get_id(uint eth_num, uint phyaddr, uint off) ++{ ++ ++ ASSERT(phyaddr < MAXEPHY); ++ ++ if (phyaddr == EPHY_NOREG) ++ return 0; ++ ++ /* read the id high */ ++ return serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESID_SERDESID0r+off); ++} ++ ++ ++void ++serdes_reset(uint eth_num, uint phyaddr) ++{ ++ uint16 ctrl; ++ ++ ASSERT(phyaddr < MAXEPHY); ++ ++ if (phyaddr == EPHY_NOREG) ++ return; ++ ++ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); ++ /* set reset flag */ ++ ctrl = serdes_rd_reg(eth_num, phyaddr, XGXS16G_IEEE0BLK_IEEECONTROL0r); ++ ctrl |= IEEE0BLK_IEEECONTROL0_RST_HW_MASK; ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_IEEE0BLK_IEEECONTROL0r, ctrl); ++ udelay(100); ++ /* check if out of reset */ ++ if (serdes_rd_reg(eth_num, phyaddr, XGXS16G_IEEE0BLK_IEEECONTROL0r) & IEEE0BLK_IEEECONTROL0_RST_HW_MASK) { ++ NET_ERROR(("et%d: %s reset not complete\n", eth_num, __FUNCTION__)); ++ } ++} ++ ++ ++int ++serdes_reset_core(uint eth_num, uint phyaddr) ++{ ++ uint16 data16; ++ uint16 serdes_id2; ++ ++ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); ++ ++ /* get serdes id */ ++ serdes_id2 = serdes_get_id(eth_num, phyaddr, 2); ++ printf("et%d %s pbyaddr(0x%x) id2(0x%x)\n", eth_num, __FUNCTION__, phyaddr, serdes_id2); ++ ++ /* unlock lane */ ++ data16 = serdes_rd_reg(eth_num, phyaddr, WC40_DIGITAL4_MISC3r); ++ data16 &= ~(DIGITAL4_MISC3_LANEDISABLE_MASK); ++ serdes_wr_reg(eth_num, phyaddr, WC40_DIGITAL4_MISC3r, data16); ++ ++ if ( phyaddr == 1 ) { ++ /* Reset the core */ ++ /* Stop PLL Sequencer and configure the core into correct mode */ ++ data16 = (XGXSBLK0_XGXSCONTROL_MODE_10G_IndLane << ++ XGXSBLK0_XGXSCONTROL_MODE_10G_SHIFT) | ++ XGXSBLK0_XGXSCONTROL_HSTL_MASK | ++ XGXSBLK0_XGXSCONTROL_CDET_EN_MASK | ++ XGXSBLK0_XGXSCONTROL_EDEN_MASK | ++ XGXSBLK0_XGXSCONTROL_AFRST_EN_MASK | ++ XGXSBLK0_XGXSCONTROL_TXCKO_DIV_MASK; ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_XGXSBLK0_XGXSCONTROLr, data16); ++ ++ /* Disable IEEE block select auto-detect. ++ * The driver will select desired block as necessary. ++ * By default, the driver keeps the XAUI block in ++ * IEEE address space. ++ */ ++ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_XGXSBLK0_MISCCONTROL1r); ++ if (XGXS16G_2p5G_ID(serdes_id2)) { ++ data16 &= ~( XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_AUTODET_MASK | ++ XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_VAL_MASK); ++ } else { ++ data16 &= ~( XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_AUTODET_MASK | ++ XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_VAL_MASK); ++#if (!defined(CONFIG_MACH_KT2)) ++ data16 |= XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_VAL_MASK; ++#endif /* (!defined(CONFIG_MACH_KT2)) */ ++ } ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_XGXSBLK0_MISCCONTROL1r, data16); ++ ++ /* disable in-band MDIO. PHY-443 */ ++ data16 = serdes_rd_reg(eth_num, phyaddr, 0x8111); ++ /* rx_inBandMdio_rst */ ++ data16 |= 1 << 3; ++ serdes_wr_reg(eth_num, phyaddr, 0x8111, data16); ++ } ++ return 0; ++} ++ ++ ++int ++serdes_start_pll(uint eth_num, uint phyaddr) ++{ ++ uint16 data16; ++ ++ if ( phyaddr == 1 ) { ++ uint32 count=250; ++ /* Start PLL Sequencer and wait for PLL to lock */ ++ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_XGXSBLK0_XGXSCONTROLr); ++ data16 |= XGXSBLK0_XGXSCONTROL_START_SEQUENCER_MASK; ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_XGXSBLK0_XGXSCONTROLr, data16); ++ ++ /* wait for PLL to lock */ ++ while (count!=0) { ++ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_XGXSBLK0_XGXSSTATUSr); ++ if ( data16 & XGXSBLK0_XGXSSTATUS_TXPLL_LOCK_MASK ) { ++ break; ++ } ++ /* wait 1 usec then dec counter */ ++ udelay(10); ++ count--; ++ } ++ if (count == 0) { ++ NET_ERROR(("%s TXPLL did not lock\n", __FUNCTION__)); ++ } ++ } ++ return 0; ++} ++ ++ ++/* ++ * Function: ++ * serdes_init ++ * Purpose: ++ * Initialize xgxs6 phys ++ * Parameters: ++ * eth_num - ethernet data ++ * phyaddr - physical address ++ * Returns: ++ * 0 ++ */ ++int ++serdes_init(uint eth_num, uint phyaddr) ++{ ++#if defined(CONFIG_MACH_SB2) ++ ++#if 0 ++ /* Speed = 10M */ ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8000); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x0c2f); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8300); ++ // iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x0120); /* Mode = AN */ ++ // iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x0000); /* Mode = Force */ ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8000); ++ // iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0000, 0x1100); /* Mode = AN */ ++ // iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0000, 0x0100); /* Mode = Force */ ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x2c2f); ++#endif ++ ++#if 0 ++ /* Speed = 100M */ ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8000); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x0c2f); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8300); ++ // iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x0120); /* Mode = AN */ ++ // iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x0000); /* Mode = Force */ ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8000); ++ // iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0000, 0x3100); /* Mode = AN */ ++ // iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0000, 0x2100); /* Mode = Force */ ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x2c2f); ++#endif ++ ++#if 0 ++ /* Speed = 1G SGMII */ ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8000); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x0c2f); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8300); ++ // iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x0120); /* Mode = AN */ ++ // iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x0000); /* Mode = Force */ ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8000); ++ // iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0000, 0x1140); /* Mode = AN */ ++ // iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0000, 0x0140); /* Mode = Force */ ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x2c3f); ++#endif ++ ++#if 1 ++ /* Auto Negotiation 10M/100M/1G ¡V SGMII Slave */ ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8000); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x0c2f); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8300); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x0100); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8000); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0000, 0x1140); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x2c3f); ++#endif ++ ++#else ++ ++ uint16 data16; ++ uint16 serdes_id0, serdes_id1, serdes_id2; ++ ++ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); ++ ++ /* get serdes id */ ++ serdes_id0 = serdes_get_id(eth_num, phyaddr, 0); ++ serdes_id1 = serdes_get_id(eth_num, phyaddr, 1); ++ serdes_id2 = serdes_get_id(eth_num, phyaddr, 2); ++ printf("%s phyaddr(0x%x) id0(0x%x) id1(0x%x) id2(0x%x)\n", __FUNCTION__, phyaddr, serdes_id0, serdes_id1, serdes_id2); ++ ++ /* get more ids */ ++ serdes_id0 = serdes_rd_reg(eth_num, phyaddr, 2); ++ serdes_id1 = serdes_rd_reg(eth_num, phyaddr, 3); ++ //printf("%s phyaddr(0x%x) SERDES PhyID_MS(0x%x) PhyID_LS(0x%x)\n", __FUNCTION__, phyaddr, serdes_id0, serdes_id1); ++ ++ /* unlock lane */ ++ data16 = serdes_rd_reg(eth_num, phyaddr, WC40_DIGITAL4_MISC3r); ++ data16 &= ~(DIGITAL4_MISC3_LANEDISABLE_MASK); ++ serdes_wr_reg(eth_num, phyaddr, WC40_DIGITAL4_MISC3r, data16); ++ ++ /* disable CL73 BAM */ ++ data16 = serdes_rd_reg(eth_num, phyaddr, 0x8372); ++ data16 &= ~(CL73_USERB0_CL73_BAMCTRL1_CL73_BAMEN_MASK); ++ serdes_wr_reg(eth_num, phyaddr, 0x8372, data16); ++ ++ /* Set Local Advertising Configuration */ ++ data16 = MII_ANA_C37_FD | MII_ANA_C37_PAUSE | MII_ANA_C37_ASYM_PAUSE; ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_COMBO_IEEE0_AUTONEGADVr, data16); ++ ++ /* Disable BAM in Independent Lane mode. Over1G AN not supported */ ++ data16 = 0; ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_BAM_NEXTPAGE_MP5_NEXTPAGECTRLr, data16); ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_BAM_NEXTPAGE_UD_FIELDr, data16); ++ ++ data16 = SERDESDIGITAL_CONTROL1000X1_CRC_CHECKER_DISABLE_MASK | ++ SERDESDIGITAL_CONTROL1000X1_DISABLE_PLL_PWRDWN_MASK; ++ /* ++ * Put the Serdes in SGMII mode ++ * bit0 = 0; in SGMII mode ++ */ ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_CONTROL1000X1r, data16); ++ ++ /* set autoneg */ ++ data16 = MII_CTRL_AE | MII_CTRL_RAN; ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_COMBO_IEEE0_MIICNTLr, data16); ++ ++ /* Disable 10G parallel detect */ ++ data16 = 0; ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_AN73_PDET_PARDET10GCONTROLr, data16); ++ ++ /* Disable BAM mode and Teton mode */ ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_BAM_NEXTPAGE_MP5_NEXTPAGECTRLr, data16); ++ ++ /* Enable lanes */ ++ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_XGXSBLK1_LANECTRL0r); ++ data16 |= XGXSBLK1_LANECTRL0_CL36_PCS_EN_RX_MASK | ++ XGXSBLK1_LANECTRL0_CL36_PCS_EN_TX_MASK; ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_XGXSBLK1_LANECTRL0r, data16); ++ ++ /* set elasticity fifo size to 13.5k to support 12k jumbo pkt size*/ ++ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_CONTROL1000X3r); ++ data16 &= SERDESDIGITAL_CONTROL1000X3_FIFO_ELASICITY_TX_RX_MASK; ++ data16 |= (1 << 2); ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_CONTROL1000X3r, data16); ++ ++ /* Enabble LPI passthru' for native mode EEE */ ++ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_REMOTEPHY_MISC5r); ++ data16 |= 0xc000; ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_REMOTEPHY_MISC5r, data16); ++ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_XGXSBLK7_EEECONTROLr); ++ data16 |= 0x0007; ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_XGXSBLK7_EEECONTROLr, data16); ++#endif ++ ++ return 0; ++} ++ ++ ++#ifdef BCMINTERNAL ++/* ++ * Function: ++ * serdes_enable_set ++ * Purpose: ++ * Enable/Disable phy ++ * Parameters: ++ * eth_num - ethernet data ++ * phyaddr - physical address ++ * enable - on/off state to set ++ * Returns: ++ * 0 ++ */ ++int ++serdes_enable_set(uint eth_num, uint phyaddr, int enable) ++{ ++ uint16 data16, mask16; ++ ++ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); ++ ++ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_XGXSBLK1_LANECTRL3r); ++ mask16 = (1 << (phyaddr-1)); /* rx lane */ ++ mask16 |= (mask16 << 4); /* add tx lane */ ++ mask16 |= 0x800; ++ if (enable) { ++ data16 &= ~(mask16); ++ } else { ++ data16 &= ~(mask16); ++ data16 |= mask16; ++ } ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_XGXSBLK1_LANECTRL3r, data16); ++ ++ return 0; ++} ++ ++ ++/* ++ * Function: ++ * serdes_speed_set ++ * Purpose: ++ * Set PHY speed ++ * Parameters: ++ * eth_num - ethernet data ++ * phyaddr - physical address ++ * speed - link speed in Mbps ++ * Returns: ++ * 0 ++ */ ++int ++serdes_speed_set(uint eth_num, uint phyaddr, int speed) ++{ ++ uint16 speed_val, mask; ++ uint16 data16; ++ uint16 speed_mii; ++ ++ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); ++ ++ if (speed > 1000) { ++ return -1; ++ } ++ ++ speed_val = 0; ++ speed_mii = 0; ++ mask = SERDESDIGITAL_MISC1_FORCE_SPEED_SEL_MASK | ++ SERDESDIGITAL_MISC1_FORCE_SPEED_MASK; ++ ++ switch (speed) { ++ case 0: ++ /* Do not change speed */ ++ return 0; ++ case 10: ++ speed_mii = MII_CTRL_SS_10; ++ break; ++ case 100: ++ speed_mii = MII_CTRL_SS_100; ++ break; ++ case 1000: ++ speed_mii = MII_CTRL_SS_1000; ++ break; ++ default: ++ return -1; ++ } ++ ++ /* Hold rxSeqStart */ ++ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_RX0_RX_CONTROLr); ++ data16 |= DSC_2_0_DSC_CTRL0_RXSEQSTART_MASK; ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_RX0_RX_CONTROLr, data16); ++ ++ /* hold TX FIFO in reset */ ++ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_CONTROL1000X3r); ++ data16 |= SERDESDIGITAL_CONTROL1000X3_TX_FIFO_RST_MASK; ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_CONTROL1000X3r, data16); ++ ++ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_MISC1r); ++ data16 &= ~(mask); ++ data16 |= speed_val; ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_MISC1r, data16); ++ ++ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_COMBO_IEEE0_MIICNTLr); ++ data16 &= ~(MII_CTRL_AE | MII_CTRL_SS_LSB | MII_CTRL_SS_MSB); ++ data16 |= speed_mii; ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_COMBO_IEEE0_MIICNTLr, data16); ++ ++ /* release rxSeqStart */ ++ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_RX0_RX_CONTROLr); ++ data16 &= ~(DSC_2_0_DSC_CTRL0_RXSEQSTART_MASK); ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_RX0_RX_CONTROLr, data16); ++ ++ /* release TX FIFO reset */ ++ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_CONTROL1000X3r); ++ data16 &= ~(SERDESDIGITAL_CONTROL1000X3_TX_FIFO_RST_MASK); ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_CONTROL1000X3r, data16); ++ ++ return 0; ++} ++ ++ ++/* ++ * Function: ++ * serdes_speed_get ++ * Purpose: ++ * Get PHY speed ++ * Parameters: ++ * eth_num - ethernet data ++ * phyaddr - physical address ++ * speed - current link speed in Mbps ++ * Returns: ++ * 0 ++ */ ++int ++serdes_speed_get(uint eth_num, uint phyaddr, int *speed) ++{ ++ uint16 data16; ++ ++ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); ++ ++ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_STATUS1000X1r); ++ ++ data16 &= SERDESDIGITAL_STATUS1000X1_SPEED_STATUS_MASK; ++ data16 >>= SERDESDIGITAL_STATUS1000X1_SPEED_STATUS_SHIFT; ++ ++ if (data16 == 3) { ++ *speed= 2500; ++ } else if (data16 == 2) { ++ *speed= 1000; ++ } else if (data16 == 1) { ++ *speed= 100; ++ } else { ++ *speed= 10; ++ } ++ ++ return 0; ++} ++ ++ ++/* ++ * Function: ++ * phy_xgxs16g1l_lb_set ++ * Purpose: ++ * Put XGXS6/FusionCore in PHY loopback ++ * Parameters: ++ * unit - StrataSwitch unit #. ++ * port - StrataSwitch port #. ++ * enable - binary value for on/off (1/0) ++ * Returns: ++ * 0 ++ */ ++int ++serdes_lb_set(uint eth_num, uint phyaddr, int enable) ++{ ++ uint16 misc_ctrl, data16; ++ uint16 lb_bit; ++ uint16 lb_mask; ++ ++ /* Configure Loopback in XAUI */ ++ misc_ctrl = serdes_rd_reg(eth_num, phyaddr, XGXS16G_XGXSBLK0_MISCCONTROL1r); ++ if (misc_ctrl & XGXSBLK0_MISCCONTROL1_PCS_DEV_EN_OVERRIDE_MASK) { ++ /* PCS */ ++ lb_bit = (enable) ? IEEE0BLK_IEEECONTROL0_GLOOPBACK_MASK : 0; ++ lb_mask = IEEE0BLK_IEEECONTROL0_GLOOPBACK_MASK; ++ } else if (misc_ctrl & XGXSBLK0_MISCCONTROL1_PMD_DEV_EN_OVERRIDE_MASK) { ++ /* PMA/PMD */ ++ lb_bit = (enable) ? 1 : 0; ++ lb_mask = 1; ++ } else { ++ /* PHY XS, DTE XS */ ++ lb_bit = (enable) ? IEEE0BLK_IEEECONTROL0_GLOOPBACK_MASK : 0; ++ lb_mask = IEEE0BLK_IEEECONTROL0_GLOOPBACK_MASK; ++ } ++ ++ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_IEEE0BLK_IEEECONTROL0r); ++ data16 &= ~(lb_mask); ++ data16 |= lb_bit; ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_IEEE0BLK_IEEECONTROL0r, data16); ++ ++ /* Configure Loopback in SerDes */ ++ lb_bit = (enable) ? MII_CTRL_LE : 0; ++ lb_mask = MII_CTRL_LE; ++ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_COMBO_IEEE0_MIICNTLr); ++ data16 &= ~(lb_mask); ++ data16 |= lb_bit; ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_COMBO_IEEE0_MIICNTLr, data16); ++ ++ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_XGXSBLK0_XGXSCONTROLr); ++ data16 |= 0x10; ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_XGXSBLK0_XGXSCONTROLr, data16); ++ ++ data16 = serdes_rd_reg(eth_num, phyaddr, 0x8017); ++ data16 = 0xff0f; ++ serdes_wr_reg(eth_num, phyaddr, 0x8017, data16); ++ ++ return 0; ++} ++ ++void ++serdes_disp_status(uint eth_num, uint phyaddr) ++{ ++ uint16 tmp0, tmp1, tmp2, tmp3; ++ ++ printf("et%d: %s: phyaddr:%d\n", eth_num, __FUNCTION__, phyaddr); ++ ++ tmp0 = serdes_get_id(eth_num, phyaddr, 0); ++ tmp1 = serdes_get_id(eth_num, phyaddr, 1); ++ tmp2 = serdes_get_id(eth_num, phyaddr, 2); ++ printf(" id0(0x%x) id1(0x%x) id2(0x%x)\n", tmp0, tmp1, tmp2); ++ ++ tmp0 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_IEEE0BLK_IEEECONTROL0r); ++ tmp1 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_IEEE0BLK_IEEECONTROL0r+1); ++ printf(" MII-Control(0): 0x%x; MII-Status(1): 0x%x\n", tmp0, tmp1); ++ ++ tmp0 = serdes_rd_reg(eth_num, phyaddr, 2); ++ tmp1 = serdes_rd_reg(eth_num, phyaddr, 3); ++ printf(" Phy ChipID(2:3): 0x%04x:0x%04x\n", tmp0, tmp1); ++ ++ tmp0 = serdes_rd_reg(eth_num, phyaddr, 4); ++ tmp1 = serdes_rd_reg(eth_num, phyaddr, 5); ++ tmp2 = serdes_rd_reg(eth_num, phyaddr, 0xf); ++ printf(" AN AD(4): 0x%x; AN LNK PARTNER(5): 0x%x; EXT STAT(f): 0x%x\n", tmp0, tmp1, tmp2); ++ ++ tmp0 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_XGXSBLK0_XGXSCONTROLr); ++ tmp1 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_XGXSBLK0_XGXSSTATUSr); ++ printf(" XGXS-Control(8000): 0x%x; XGXS-Status(8001): 0x%x\n", tmp0, tmp1); ++ ++ tmp0 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_XGXSBLK0_MMDSELECTr); ++ tmp1 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_XGXSBLK0_MISCCONTROL1r); ++ printf(" XGXS BLK0 MMD Select(800d): 0x%x; XGXS BLK0 MISC CTRL(800e): 0x%x\n", tmp0, tmp1); ++ ++ tmp0 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_XGXSBLK1_LANECTRL0r); ++ tmp1 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_XGXSBLK1_LANECTRL3r); ++ printf(" XGXS BLK1 LNCTRL0(8015): 0x%x; XGXS BLK1_LNCTRL3(8018): 0x%x\n", tmp0, tmp1); ++ ++ tmp0 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_RX0_RX_CONTROLr); ++ tmp1 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_AN73_PDET_PARDET10GCONTROLr); ++ tmp2 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_XGXSBLK7_EEECONTROLr); ++ printf(" XGXS RX0 CTRL(80b1): 0x%x; XGXS AN73 PARDET CTRL(8131): 0x%x; XGXS BLK7 EEECTRL(8150): 0x%x\n", tmp0, tmp1, tmp2); ++ ++ tmp0 = serdes_rd_reg(eth_num, phyaddr, 0x8111); ++ tmp1 = serdes_rd_reg(eth_num, phyaddr, 0x8372); ++ printf(" (8111): 0x%x; (8372): 0x%x\n", tmp0, tmp1); ++ ++ tmp0 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_CONTROL1000X1r); ++ tmp1 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_CONTROL1000X2r); ++ tmp2 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_CONTROL1000X3r); ++ printf(" XGXS SERDES DIG CTRL 1000X1(8300): 0x%x; XGXS SERDES DIG CTRL 1000X2(8301): 0x%x; XGXS SERDES DIGITAL CTRL 1000X3r(8302): 0x%x\n", tmp0, tmp1, tmp2); ++ ++ tmp0 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_STATUS1000X1r); ++ tmp1 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_MISC1r); ++ printf(" XGXS SERDES DIG STATUS 1000X1(8304): 0x%x; XGXS SERDES DIG MISC1(8308): 0x%x\n", tmp0, tmp1); ++ ++ tmp0 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESID_SERDESID0r); ++ tmp1 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESID_SERDESID1r); ++ printf(" XGXS SERDESID0(8310): 0x%x; XGXS SERDESID1(8311): 0x%x\n", tmp0, tmp1); ++ ++ tmp0 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESID_SERDESID2r); ++ tmp1 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESID_SERDESID3r); ++ printf(" XGXS SERDESID0(8312): 0x%x; XGXS SERDESID1(8313): 0x%x\n", tmp0, tmp1); ++ ++ tmp0 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_REMOTEPHY_MISC3r); ++ tmp1 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_REMOTEPHY_MISC5r); ++ printf(" XGXS REMOTEPHY MISC3(833c): 0x%x; XGXS REMOTEPHY MISC5(833e): 0x%x\n", tmp0, tmp1); ++ ++ tmp0 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_BAM_NEXTPAGE_MP5_NEXTPAGECTRLr); ++ tmp1 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_BAM_NEXTPAGE_UD_FIELDr); ++ printf(" XGXS BAM MP5_NEXTPAGECTRL(8350): 0x%x; XGXS BAM NP UD FIELDr(8357): 0x%x\n", tmp0, tmp1); ++ ++ tmp0 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_COMBO_IEEE0_MIICNTLr); ++ tmp1 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_COMBO_IEEE0_AUTONEGADVr); ++ printf(" XGXS COMBO IEEE0 MIICNTL(ffe0): 0x%x; XGXS COMBO IEEE0 AUTONEGADVr(ffe4): 0x%x\n", tmp0, tmp1); ++ ++ tmp0 = serdes_rd_reg(eth_num, phyaddr, 0x8050); ++ tmp1 = serdes_rd_reg(eth_num, phyaddr, 0x8122); ++ printf(" (8050): 0x%x; (8122): 0x%x\n", tmp0, tmp1); ++ ++ tmp0 = serdes_rd_reg(eth_num, phyaddr, 0x80b0); ++ tmp1 = serdes_rd_reg(eth_num, phyaddr, 0x80c0); ++ tmp2 = serdes_rd_reg(eth_num, phyaddr, 0x80d0); ++ tmp3 = serdes_rd_reg(eth_num, phyaddr, 0x80e0); ++ printf(" (80b0): 0x%x; (80c0): 0x%x; (80d0): 0x%x, (80e0): 0x%x\n", tmp0, tmp1, tmp2, tmp3); ++ ++ tmp0 = serdes_rd_reg(eth_num, phyaddr, 0xffe1); ++ printf(" (ffe1): 0x%x\n", tmp0); ++ ++} ++#endif /* BCMINTERNAL */ ++ ++ ++#if (defined(CONFIG_SERDES_ASYMMETRIC_MODE)) ++/* ++ * Function: ++ * serdes_speeddpx_set ++ * Purpose: ++ * Set serdes speed dpx ++ * Parameters: ++ * eth_num - ethernet data ++ * phyaddr - physical address ++ * speed - link speed in Mbps ++ * fulldpx - link dpx ++ * Returns: ++ * 0 ++ */ ++int ++serdes_speeddpx_set(uint eth_num, uint phyaddr, int speed, int fulldpx) ++{ ++ uint16 speed_val, mask; ++ uint16 data16; ++ uint16 speed_mii; ++ ++ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); ++ ++ if (speed > 1000) { ++ return -1; ++ } ++ ++ speed_val = 0; ++ speed_mii = 0; ++ mask = SERDESDIGITAL_MISC1_FORCE_SPEED_SEL_MASK | ++ SERDESDIGITAL_MISC1_FORCE_SPEED_MASK; ++ ++ switch (speed) { ++ case 0: ++ /* Do not change speed */ ++ return 0; ++ case 10: ++ speed_mii = MII_CTRL_SS_10; ++ break; ++ case 100: ++ speed_mii = MII_CTRL_SS_100; ++ break; ++ case 1000: ++ speed_mii = MII_CTRL_SS_1000; ++ break; ++ default: ++ return -1; ++ } ++ ++ if (fulldpx) ++ speed_mii |= MII_CTRL_FD; ++ ++ /* Hold rxSeqStart */ ++ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_RX0_RX_CONTROLr); ++ data16 |= DSC_2_0_DSC_CTRL0_RXSEQSTART_MASK; ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_RX0_RX_CONTROLr, data16); ++ ++ /* hold TX FIFO in reset */ ++ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_CONTROL1000X3r); ++ data16 |= SERDESDIGITAL_CONTROL1000X3_TX_FIFO_RST_MASK; ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_CONTROL1000X3r, data16); ++ ++ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_MISC1r); ++ data16 &= ~(mask); ++ data16 |= speed_val; ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_MISC1r, data16); ++ ++ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_COMBO_IEEE0_MIICNTLr); ++ data16 &= ~(MII_CTRL_AE | MII_CTRL_RAN | MII_CTRL_SS_LSB | MII_CTRL_SS_MSB | MII_CTRL_FD); ++ data16 |= speed_mii; ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_COMBO_IEEE0_MIICNTLr, data16); ++ ++ /* release rxSeqStart */ ++ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_RX0_RX_CONTROLr); ++ data16 &= ~(DSC_2_0_DSC_CTRL0_RXSEQSTART_MASK); ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_RX0_RX_CONTROLr, data16); ++ ++ /* release TX FIFO reset */ ++ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_CONTROL1000X3r); ++ data16 &= ~(SERDESDIGITAL_CONTROL1000X3_TX_FIFO_RST_MASK); ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_CONTROL1000X3r, data16); ++ ++ return 0; ++} ++ ++int ++serdes_set_asym_mode(uint eth_num, uint phyaddr) ++{ ++ uint16 data16; ++ uint32 txclkctrlreg[] = {0x0000, 0x8065, 0x8075, 0x8085}; ++ uint32 rxclkctrlreg[] = {0x0000, 0x80bc, 0x80cc, 0x80dc}; ++ uint32 spd[] = {0x0000, 0x7120, 0x7120, 0x7110}; ++ uint32 clkctrlmsk[] = {0x0000, 0x0040, 0x0040, 0x0040}; ++ uint32 clkctrlval[] = {0x0000, 0x0040, 0x0040, 0x0000}; ++ ++ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); ++ ++ printk("et%d: %s: setting serdes asymmetrice mode\n", eth_num, __FUNCTION__); ++ ++ /* set speed */ ++ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_MISC1r); ++ //printk("et%d: %s: read 0x%x from 0x%x\n", eth_num, __FUNCTION__, data16, XGXS16G_SERDESDIGITAL_MISC1r); ++ data16 &= 0x0f00; ++ data16 |= spd[phyaddr]; ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_MISC1r, data16); ++ //printk("et%d: %s: write 0x%x to 0x%x\n", eth_num, __FUNCTION__, data16, XGXS16G_SERDESDIGITAL_MISC1r); ++ ++ /* Enable asymmetric mode */ ++ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_TX_LN_SWAP1r); ++ //printk("et%d: %s: read 0x%x from 0x%x\n", eth_num, __FUNCTION__, data16, XGXS16G_TX_LN_SWAP1r); ++ data16 |= 0x0100; ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_TX_LN_SWAP1r, data16); ++ //printk("et%d: %s: write 0x%x to 0x%x\n", eth_num, __FUNCTION__, data16, XGXS16G_TX_LN_SWAP1r); ++ ++ /* set tx clock control bit */ ++ data16 = serdes_rd_reg(eth_num, phyaddr, txclkctrlreg[phyaddr]); ++ //printk("et%d: %s: read 0x%x from 0x%x\n", eth_num, __FUNCTION__, data16, txclkctrlreg[phyaddr]); ++ data16 &= ~(clkctrlmsk[phyaddr]); ++ data16 |= clkctrlval[phyaddr]; ++ serdes_wr_reg(eth_num, phyaddr, txclkctrlreg[phyaddr], data16); ++ //printk("et%d: %s: write 0x%x to 0x%x\n", eth_num, __FUNCTION__, data16, txclkctrlreg[phyaddr]); ++ ++ /* set rx clock control bit */ ++ data16 = serdes_rd_reg(eth_num, phyaddr, rxclkctrlreg[phyaddr]); ++ //printk("et%d: %s: read 0x%x from 0x%x\n", eth_num, __FUNCTION__, data16, rxclkctrlreg[phyaddr]); ++ data16 &= ~(clkctrlmsk[phyaddr]); ++ data16 |= clkctrlval[phyaddr]; ++ serdes_wr_reg(eth_num, phyaddr, rxclkctrlreg[phyaddr], data16); ++ //printk("et%d: %s: write 0x%x to 0x%x\n", eth_num, __FUNCTION__, data16, rxclkctrlreg[phyaddr]); ++ ++ data16 = 0xffff; ++ serdes_wr_reg(eth_num, phyaddr, XGXS16G_XGXSBLK1_LANECTRL1r, data16); ++ //printk("et%d: %s: write 0x%x to 0x%x\n", eth_num, __FUNCTION__, data16, XGXS16G_XGXSBLK1_LANECTRL1r); ++ ++ return 0; ++} ++ ++#endif /* (defined(CONFIG_SERDES_ASYMMETRIC_MODE)) */ ++ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/bcmutils.c b/drivers/net/ethernet/broadcom/gmac/src/shared/bcmutils.c +--- a/drivers/net/ethernet/broadcom/gmac/src/shared/bcmutils.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/shared/bcmutils.c 2017-11-09 17:53:44.032290000 +0800 +@@ -0,0 +1,3389 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Driver O/S-independent utility routines ++ * ++ * $Id: bcmutils.c 325951 2012-04-05 06:03:27Z $ ++ */ ++ ++#include ++#include ++#include ++#if defined(__FreeBSD__) || defined(__NetBSD__) ++#include ++#else ++#include ++#endif ++#ifdef BCMDRIVER ++ ++#include ++#include ++#include ++#include ++ ++#else /* !BCMDRIVER */ ++ ++#include ++#include ++#include ++ ++#if defined(BCMEXTSUP) ++#include ++#endif ++ ++#endif /* !BCMDRIVER */ ++ ++#if defined(_WIN32) || defined(NDIS) || defined(__vxworks) || defined(_CFE_) ++#include ++#endif ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef BCMPERFSTATS ++#include ++#endif ++#include ++void *_bcmutils_dummy_fn = NULL; ++ ++#ifdef BCMDRIVER ++ ++#ifdef WLC_LOW ++/* nvram vars cache */ ++static char *nvram_vars = NULL; ++static int vars_len = -1; ++#endif /* WLC_LOW */ ++ ++int ++pktpool_init(osl_t *osh, pktpool_t *pktp, int *pplen, int plen, bool istx) ++{ ++ int i, err = BCME_OK; ++ void *p; ++ int pktplen; ++ ++ ASSERT(pktp != NULL); ++ ASSERT(osh != NULL); ++ ASSERT(pplen != NULL); ++ ++ pktplen = *pplen; ++ ++ bzero(pktp, sizeof(pktpool_t)); ++ pktp->inited = TRUE; ++ pktp->istx = istx ? TRUE : FALSE; ++ pktp->plen = (uint16)plen; ++ *pplen = 0; ++ ++ pktp->maxlen = PKTPOOL_LEN_MAX; ++ if (pktplen > pktp->maxlen) ++ pktplen = pktp->maxlen; ++ ++ for (i = 0; i < pktplen; i++) { ++ p = PKTGET(osh, plen, pktp->istx); ++ if (p == NULL) { ++ /* Not able to allocate all requested pkts ++ * so just return what was actually allocated ++ * We can add to the pool later ++ */ ++ if (pktp->w == 0) { ++ err = BCME_NOMEM; ++ } ++ ++ goto exit; ++ } ++ ++ PKTSETPOOL(osh, p, TRUE, pktp); ++ pktp->q[i] = p; ++ pktp->w++; ++ pktp->len++; ++#ifdef BCMDBG_POOL ++ pktp->dbg_q[pktp->dbg_qlen++].p = p; ++#endif ++ } ++ ++exit: ++ *pplen = pktp->w; ++ pktp->len++; /* Add one for end */ ++ return err; ++} ++ ++int ++pktpool_deinit(osl_t *osh, pktpool_t *pktp) ++{ ++ int i; ++ int cnt; ++ ++ ASSERT(osh != NULL); ++ ASSERT(pktp != NULL); ++ ++ cnt = pktp->len; ++ for (i = 0; i < cnt; i++) { ++ if (pktp->q[i] != NULL) { ++ PKTSETPOOL(osh, pktp->q[i], FALSE, NULL); ++ PKTFREE(osh, pktp->q[i], pktp->istx); ++ pktp->q[i] = NULL; ++ pktp->len--; ++ } ++#ifdef BCMDBG_POOL ++ if (pktp->dbg_q[i].p != NULL) { ++ pktp->dbg_q[i].p = NULL; ++ } ++#endif ++ } ++ pktp->inited = FALSE; ++ ++ /* Are there still pending pkts? */ ++ ASSERT(pktpool_len(pktp) == 0); ++ ++ return 0; ++} ++ ++int ++pktpool_fill(osl_t *osh, pktpool_t *pktp, bool minimal) ++{ ++ void *p; ++ int err = 0; ++ int len, psize, maxlen; ++ ++ ASSERT(pktpool_plen(pktp) != 0); ++ ++ maxlen = pktpool_maxlen(pktp); ++ psize = minimal ? (maxlen >> 2) : maxlen; ++ len = pktpool_len(pktp); ++ for (; len < psize; len++) { ++ p = PKTGET(osh, pktpool_plen(pktp), FALSE); ++ if (p == NULL) { ++ err = BCME_NOMEM; ++ break; ++ } ++ ++ if (pktpool_add(pktp, p) != BCME_OK) { ++ PKTFREE(osh, p, FALSE); ++ err = BCME_ERROR; ++ break; ++ } ++ } ++ ++ return err; ++} ++ ++uint16 ++pktpool_avail(pktpool_t *pktp) ++{ ++ if (pktp->w == pktp->r) { ++ return 0; ++ } ++ ++ return (pktp->w > pktp->r) ? (pktp->w - pktp->r) : ((pktp->len) - (pktp->r - pktp->w)); ++} ++ ++static void * ++pktpool_deq(pktpool_t *pktp) ++{ ++ void *p; ++ ++ if (pktp->r == pktp->w) { ++ return NULL; ++ } ++ ++ p = pktp->q[pktp->r]; ++ ASSERT(p != NULL); ++ ++ pktp->q[pktp->r++] = NULL; ++ pktp->r %= (pktp->len); ++ ++ return p; ++} ++ ++static void ++pktpool_enq(pktpool_t *pktp, void *p) ++{ ++ uint16 next; ++ ++ ASSERT(p != NULL); ++ ++ next = (pktp->w + 1) % (pktp->len); ++ if (next == pktp->r) { ++ /* Should not happen; otherwise pkt leak */ ++ ASSERT(0); ++ return; ++ } ++ ++ ASSERT(pktp->q[pktp->w] == NULL); ++ ++ pktp->q[pktp->w] = p; ++ pktp->w = next; ++} ++ ++int ++pktpool_avail_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg) ++{ ++ int i; ++ ++ ASSERT(cb != NULL); ++ ++ i = pktp->cbcnt; ++ if (i == PKTPOOL_CB_MAX) { ++ return BCME_ERROR; ++ } ++ ++ ASSERT(pktp->cbs[i].cb == NULL); ++ pktp->cbs[i].cb = cb; ++ pktp->cbs[i].arg = arg; ++ pktp->cbcnt++; ++ ++ return 0; ++} ++ ++int ++pktpool_empty_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg) ++{ ++ int i; ++ ++ ASSERT(cb != NULL); ++ ++ i = pktp->ecbcnt; ++ if (i == PKTPOOL_CB_MAX) { ++ return BCME_ERROR; ++ } ++ ++ ASSERT(pktp->ecbs[i].cb == NULL); ++ pktp->ecbs[i].cb = cb; ++ pktp->ecbs[i].arg = arg; ++ pktp->ecbcnt++; ++ ++ return 0; ++} ++ ++static int ++pktpool_empty_notify(pktpool_t *pktp) ++{ ++ int i; ++ ++ pktp->empty = TRUE; ++ for (i = 0; i < pktp->ecbcnt; i++) { ++ ASSERT(pktp->ecbs[i].cb != NULL); ++ pktp->ecbs[i].cb(pktp, pktp->ecbs[i].arg); ++ } ++ pktp->empty = FALSE; ++ ++ return 0; ++} ++ ++#ifdef BCMDBG_POOL ++int ++pktpool_dbg_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg) ++{ ++ int i; ++ ++ ASSERT(cb); ++ ++ i = pktp->dbg_cbcnt; ++ if (i == PKTPOOL_CB_MAX) ++ return BCME_ERROR; ++ ++ ASSERT(pktp->dbg_cbs[i].cb == NULL); ++ pktp->dbg_cbs[i].cb = cb; ++ pktp->dbg_cbs[i].arg = arg; ++ pktp->dbg_cbcnt++; ++ ++ return 0; ++} ++ ++int pktpool_dbg_notify(pktpool_t *pktp); ++ ++int ++pktpool_dbg_notify(pktpool_t *pktp) ++{ ++ int i; ++ ++ for (i = 0; i < pktp->dbg_cbcnt; i++) { ++ ASSERT(pktp->dbg_cbs[i].cb); ++ pktp->dbg_cbs[i].cb(pktp, pktp->dbg_cbs[i].arg); ++ } ++ ++ return 0; ++} ++ ++int ++pktpool_dbg_dump(pktpool_t *pktp) ++{ ++ int i; ++ ++ printf("pool len=%d maxlen=%d\n", pktp->dbg_qlen, pktp->maxlen); ++ for (i = 0; i < pktp->dbg_qlen; i++) { ++ ASSERT(pktp->dbg_q[i].p); ++ printf("%d, p: 0x%x dur:%lu us state:%d\n", i, ++ pktp->dbg_q[i].p, pktp->dbg_q[i].dur/100, PKTPOOLSTATE(pktp->dbg_q[i].p)); ++ } ++ ++ return 0; ++} ++ ++int ++pktpool_stats_dump(pktpool_t *pktp, pktpool_stats_t *stats) ++{ ++ int i; ++ int state; ++ ++ bzero(stats, sizeof(pktpool_stats_t)); ++ for (i = 0; i < pktp->dbg_qlen; i++) { ++ ASSERT(pktp->dbg_q[i].p != NULL); ++ ++ state = PKTPOOLSTATE(pktp->dbg_q[i].p); ++ switch (state) { ++ case POOL_TXENQ: ++ stats->enq++; break; ++ case POOL_TXDH: ++ stats->txdh++; break; ++ case POOL_TXD11: ++ stats->txd11++; break; ++ case POOL_RXDH: ++ stats->rxdh++; break; ++ case POOL_RXD11: ++ stats->rxd11++; break; ++ case POOL_RXFILL: ++ stats->rxfill++; break; ++ case POOL_IDLE: ++ stats->idle++; break; ++ } ++ } ++ ++ return 0; ++} ++ ++int ++pktpool_start_trigger(pktpool_t *pktp, void *p) ++{ ++ uint32 cycles, i; ++ ++ if (!PKTPOOL(NULL, p)) { ++ return 0; ++ } ++ ++ OSL_GETCYCLES(cycles); ++ ++ for (i = 0; i < pktp->dbg_qlen; i++) { ++ ASSERT(pktp->dbg_q[i].p != NULL); ++ ++ if (pktp->dbg_q[i].p == p) { ++ pktp->dbg_q[i].cycles = cycles; ++ break; ++ } ++ } ++ ++ return 0; ++} ++ ++int pktpool_stop_trigger(pktpool_t *pktp, void *p); ++int ++pktpool_stop_trigger(pktpool_t *pktp, void *p) ++{ ++ uint32 cycles, i; ++ ++ if (!PKTPOOL(NULL, p)) { ++ return 0; ++ } ++ ++ OSL_GETCYCLES(cycles); ++ ++ for (i = 0; i < pktp->dbg_qlen; i++) { ++ ASSERT(pktp->dbg_q[i].p != NULL); ++ ++ if (pktp->dbg_q[i].p == p) { ++ if (pktp->dbg_q[i].cycles == 0) ++ break; ++ ++ if (cycles >= pktp->dbg_q[i].cycles) ++ pktp->dbg_q[i].dur = cycles - pktp->dbg_q[i].cycles; ++ else ++ pktp->dbg_q[i].dur = ++ (((uint32)-1) - pktp->dbg_q[i].cycles) + cycles + 1; ++ ++ pktp->dbg_q[i].cycles = 0; ++ break; ++ } ++ } ++ ++ return 0; ++} ++#endif /* BCMDBG_POOL */ ++ ++int ++pktpool_avail_notify_normal(osl_t *osh, pktpool_t *pktp) ++{ ++ ASSERT(pktp); ++ pktp->availcb_excl = NULL; ++ return 0; ++} ++ ++int ++pktpool_avail_notify_exclusive(osl_t *osh, pktpool_t *pktp, pktpool_cb_t cb) ++{ ++ int i; ++ ++ ASSERT(pktp); ++ ASSERT(pktp->availcb_excl == NULL); ++ for (i = 0; i < pktp->cbcnt; i++) { ++ if (cb == pktp->cbs[i].cb) { ++ pktp->availcb_excl = &pktp->cbs[i]; ++ break; ++ } ++ } ++ ++ if (pktp->availcb_excl == NULL) { ++ return BCME_ERROR; ++ } else { ++ return 0; ++ } ++} ++ ++static int ++pktpool_avail_notify(pktpool_t *pktp) ++{ ++ int i, k, idx; ++ int avail; ++ ++ ASSERT(pktp); ++ if (pktp->availcb_excl != NULL) { ++ pktp->availcb_excl->cb(pktp, pktp->availcb_excl->arg); ++ return 0; ++ } ++ ++ k = pktp->cbcnt - 1; ++ for (i = 0; i < pktp->cbcnt; i++) { ++ avail = pktpool_avail(pktp); ++ ++ if (avail) { ++ if (pktp->cbtoggle) { ++ idx = i; ++ } else { ++ idx = k--; ++ } ++ ++ ASSERT(pktp->cbs[idx].cb != NULL); ++ pktp->cbs[idx].cb(pktp, pktp->cbs[idx].arg); ++ } ++ } ++ ++ /* Alternate between filling from head or tail ++ */ ++ pktp->cbtoggle ^= 1; ++ ++ return 0; ++} ++ ++void * ++pktpool_get(pktpool_t *pktp) ++{ ++ void *p; ++ ++ p = pktpool_deq(pktp); ++ ++ if (p == NULL) { ++ /* Notify and try to reclaim tx pkts */ ++ if (pktp->ecbcnt) { ++ pktpool_empty_notify(pktp); ++ } ++ ++ p = pktpool_deq(pktp); ++ } ++ ++ return p; ++} ++ ++void ++pktpool_free(pktpool_t *pktp, void *p) ++{ ++ ASSERT(p != NULL); ++ ++#ifdef BCMDBG_POOL ++ /* pktpool_stop_trigger(pktp, p); */ ++#endif ++ ++ pktpool_enq(pktp, p); ++ ++ if (pktp->emptycb_disable) { ++ return; ++ } ++ ++ if (pktp->cbcnt) { ++ if (pktp->empty == FALSE) { ++ pktpool_avail_notify(pktp); ++ } ++ } ++} ++ ++int ++pktpool_add(pktpool_t *pktp, void *p) ++{ ++ ASSERT(p != NULL); ++ ++ if (pktpool_len(pktp) == pktp->maxlen) { ++ return BCME_RANGE; ++ } ++ ++ ASSERT(pktpool_plen(pktp) == PKTLEN(NULL, p)); /* pkts in pool have same length */ ++ PKTSETPOOL(NULL, p, TRUE, pktp); ++ ++ pktp->len++; ++ if (pktp->r > pktp->w) { ++ /* Add to tail */ ++ ASSERT(pktp->q[pktp->len - 1] == NULL); ++ pktp->q[pktp->len - 1] = p; ++ } else { ++ pktpool_enq(pktp, p); ++ } ++ ++#ifdef BCMDBG_POOL ++ pktp->dbg_q[pktp->dbg_qlen++].p = p; ++#endif ++ ++ return 0; ++} ++ ++int ++pktpool_setmaxlen(pktpool_t *pktp, uint16 maxlen) ++{ ++ if (maxlen > PKTPOOL_LEN_MAX) ++ maxlen = PKTPOOL_LEN_MAX; ++ ++ /* if pool is already beyond maxlen, then just cap it ++ * since we currently do not reduce the pool len ++ * already allocated ++ */ ++ pktp->maxlen = (pktpool_len(pktp) > maxlen) ? pktpool_len(pktp) : maxlen; ++ ++ return pktp->maxlen; ++} ++ ++void ++pktpool_emptycb_disable(pktpool_t *pktp, bool disable) ++{ ++ ASSERT(pktp); ++ ++ pktp->emptycb_disable = disable; ++} ++ ++bool ++pktpool_emptycb_disabled(pktpool_t *pktp) ++{ ++ ASSERT(pktp); ++ return pktp->emptycb_disable; ++} ++ ++/* copy a pkt buffer chain into a buffer */ ++uint ++pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf) ++{ ++ uint n, ret = 0; ++ ++ if (len < 0) { ++ len = 4096; /* "infinite" */ ++ } ++ ++ /* skip 'offset' bytes */ ++ for (; p && offset; p = PKTNEXT(osh, p)) { ++ if (offset < (uint)PKTLEN(osh, p)) { ++ break; ++ } ++ offset -= PKTLEN(osh, p); ++ } ++ ++ if (!p) { ++ return 0; ++ } ++ ++ /* copy the data */ ++ for (; p && len; p = PKTNEXT(osh, p)) { ++ n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len); ++ bcopy(PKTDATA(osh, p) + offset, buf, n); ++ buf += n; ++ len -= n; ++ ret += n; ++ offset = 0; ++ } ++ ++ return ret; ++} ++ ++/* copy a buffer into a pkt buffer chain */ ++uint ++pktfrombuf(osl_t *osh, void *p, uint offset, int len, uchar *buf) ++{ ++ uint n, ret = 0; ++ ++ /* skip 'offset' bytes */ ++ for (; p && offset; p = PKTNEXT(osh, p)) { ++ if (offset < (uint)PKTLEN(osh, p)) { ++ break; ++ } ++ offset -= PKTLEN(osh, p); ++ } ++ ++ if (!p) { ++ return 0; ++ } ++ ++ /* copy the data */ ++ for (; p && len; p = PKTNEXT(osh, p)) { ++ n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len); ++ bcopy(buf, PKTDATA(osh, p) + offset, n); ++ buf += n; ++ len -= n; ++ ret += n; ++ offset = 0; ++ } ++ ++ return ret; ++} ++ ++#ifdef NOTYET ++/* copy data from one pkt buffer (chain) to another */ ++uint ++pkt2pktcopy(osl_t *osh, void *p1, uint offs1, void *p2, uint offs2, int maxlen) ++{ ++ uint8 *dp1, *dp2; ++ uint len1, len2, copylen, totallen; ++ ++ for (; p1 && offs; p1 = PKTNEXT(osh, p1)) { ++ if (offs1 < (uint)PKTLEN(osh, p1)) { ++ break; ++ } ++ offs1 -= PKTLEN(osh, p1); ++ } ++ for (; p2 && offs; p2 = PKTNEXT(osh, p2)) { ++ if (offs2 < (uint)PKTLEN(osh, p2)) { ++ break; ++ } ++ offs2 -= PKTLEN(osh, p2); ++ } ++ ++ /* Heck w/it, only need the above for now */ ++} ++#endif /* NOTYET */ ++ ++ ++/* return total length of buffer chain */ ++uint BCMFASTPATH ++pkttotlen(osl_t *osh, void *p) ++{ ++ uint total; ++ int len; ++ ++ total = 0; ++ for (; p; p = PKTNEXT(osh, p)) { ++ len = PKTLEN(osh, p); ++#ifdef MACOSX ++ if (len < 0) { ++ /* Bad packet length, just drop and exit */ ++ printf("wl: pkttotlen bad (%p,%d)\n", p, len); ++ break; ++ } ++#endif /* MACOSX */ ++ total += len; ++ } ++ ++ return (total); ++} ++ ++/* return the last buffer of chained pkt */ ++void * ++pktlast(osl_t *osh, void *p) ++{ ++ for (; PKTNEXT(osh, p); p = PKTNEXT(osh, p)) { ++ ; ++ } ++ ++ return (p); ++} ++ ++/* count segments of a chained packet */ ++uint BCMFASTPATH ++pktsegcnt(osl_t *osh, void *p) ++{ ++ uint cnt; ++ ++ for (cnt = 0; p; p = PKTNEXT(osh, p)) { ++ cnt++; ++ } ++ ++ return cnt; ++} ++ ++ ++/* count segments of a chained packet */ ++uint BCMFASTPATH ++pktsegcnt_war(osl_t *osh, void *p) ++{ ++ uint cnt; ++ uint8 *pktdata; ++ uint len, remain, align64; ++ ++ for (cnt = 0; p; p = PKTNEXT(osh, p)) { ++ cnt++; ++ len = PKTLEN(osh, p); ++ if (len > 128) { ++ pktdata = (uint8 *)PKTDATA(osh, p); /* starting address of data */ ++ /* Check for page boundary straddle (2048B) */ ++ if (((uintptr)pktdata & ~0x7ff) != ((uintptr)(pktdata+len) & ~0x7ff)) { ++ cnt++; ++ } ++ ++ align64 = (uint)((uintptr)pktdata & 0x3f); /* aligned to 64B */ ++ align64 = (64 - align64) & 0x3f; ++ len -= align64; /* bytes from aligned 64B to end */ ++ /* if aligned to 128B, check for MOD 128 between 1 to 4B */ ++ remain = len % 128; ++ if (remain > 0 && remain <= 4) { ++ cnt++; /* add extra seg */ ++ } ++ } ++ } ++ ++ return cnt; ++} ++ ++uint8 * BCMFASTPATH ++pktdataoffset(osl_t *osh, void *p, uint offset) ++{ ++ uint total = pkttotlen(osh, p); ++ uint pkt_off = 0, len = 0; ++ uint8 *pdata = (uint8 *) PKTDATA(osh, p); ++ ++ if (offset > total) { ++ return NULL; ++ } ++ ++ for (; p; p = PKTNEXT(osh, p)) { ++ pdata = (uint8 *) PKTDATA(osh, p); ++ pkt_off = offset - len; ++ len += PKTLEN(osh, p); ++ if (len > offset) { ++ break; ++ } ++ } ++ return (uint8*) (pdata+pkt_off); ++} ++ ++ ++/* given a offset in pdata, find the pkt seg hdr */ ++void * ++pktoffset(osl_t *osh, void *p, uint offset) ++{ ++ uint total = pkttotlen(osh, p); ++ uint len = 0; ++ ++ if (offset > total) { ++ return NULL; ++ } ++ ++ for (; p; p = PKTNEXT(osh, p)) { ++ len += PKTLEN(osh, p); ++ if (len > offset) { ++ break; ++ } ++ } ++ return p; ++} ++ ++/* ++ * osl multiple-precedence packet queue ++ * hi_prec is always >= the number of the highest non-empty precedence ++ */ ++void * BCMFASTPATH ++pktq_penq(struct pktq *pq, int prec, void *p) ++{ ++ struct pktq_prec *q; ++ ++ ASSERT(prec >= 0 && prec < pq->num_prec); ++ ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */ ++ ++ ASSERT(!pktq_full(pq)); ++ ASSERT(!pktq_pfull(pq, prec)); ++ ++ q = &pq->q[prec]; ++ ++ if (q->head) { ++ PKTSETLINK(q->tail, p); ++ } else { ++ q->head = p; ++ } ++ ++ q->tail = p; ++ q->len++; ++ ++ pq->len++; ++ ++ if (pq->hi_prec < prec) { ++ pq->hi_prec = (uint8)prec; ++ } ++ ++ return p; ++} ++ ++void * BCMFASTPATH ++pktq_penq_head(struct pktq *pq, int prec, void *p) ++{ ++ struct pktq_prec *q; ++ ++ ASSERT(prec >= 0 && prec < pq->num_prec); ++ ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */ ++ ++ ASSERT(!pktq_full(pq)); ++ ASSERT(!pktq_pfull(pq, prec)); ++ ++ q = &pq->q[prec]; ++ ++ if (q->head == NULL) { ++ q->tail = p; ++ } ++ ++ PKTSETLINK(p, q->head); ++ q->head = p; ++ q->len++; ++ ++ pq->len++; ++ ++ if (pq->hi_prec < prec) { ++ pq->hi_prec = (uint8)prec; ++ } ++ ++ return p; ++} ++ ++void * BCMFASTPATH ++pktq_pdeq(struct pktq *pq, int prec) ++{ ++ struct pktq_prec *q; ++ void *p; ++ ++ ASSERT(prec >= 0 && prec < pq->num_prec); ++ ++ q = &pq->q[prec]; ++ ++ if ((p = q->head) == NULL) { ++ return NULL; ++ } ++ ++ if ((q->head = PKTLINK(p)) == NULL) { ++ q->tail = NULL; ++ } ++ ++ q->len--; ++ ++ pq->len--; ++ ++ PKTSETLINK(p, NULL); ++ ++ return p; ++} ++ ++void * BCMFASTPATH ++pktq_pdeq_prev(struct pktq *pq, int prec, void *prev_p) ++{ ++ struct pktq_prec *q; ++ void *p; ++ ++ ASSERT(prec >= 0 && prec < pq->num_prec); ++ ++ q = &pq->q[prec]; ++ ++ if (prev_p == NULL) { ++ return NULL; ++ } ++ ++ if ((p = PKTLINK(prev_p)) == NULL) { ++ return NULL; ++ } ++ ++ q->len--; ++ ++ pq->len--; ++ ++ PKTSETLINK(prev_p, PKTLINK(p)); ++ PKTSETLINK(p, NULL); ++ ++ return p; ++} ++ ++void * BCMFASTPATH ++pktq_pdeq_tail(struct pktq *pq, int prec) ++{ ++ struct pktq_prec *q; ++ void *p, *prev; ++ ++ ASSERT(prec >= 0 && prec < pq->num_prec); ++ ++ q = &pq->q[prec]; ++ ++ if ((p = q->head) == NULL) { ++ return NULL; ++ } ++ ++ for (prev = NULL; p != q->tail; p = PKTLINK(p)) { ++ prev = p; ++ } ++ ++ if (prev) { ++ PKTSETLINK(prev, NULL); ++ } else { ++ q->head = NULL; ++ } ++ ++ q->tail = prev; ++ q->len--; ++ ++ pq->len--; ++ ++ return p; ++} ++ ++void ++pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir, ifpkt_cb_t fn, int arg) ++{ ++ struct pktq_prec *q; ++ void *p, *prev = NULL; ++ ++ q = &pq->q[prec]; ++ p = q->head; ++ while (p) { ++ if (fn == NULL || (*fn)(p, arg)) { ++ bool head = (p == q->head); ++ if (head) { ++ q->head = PKTLINK(p); ++ } else { ++ PKTSETLINK(prev, PKTLINK(p)); ++ } ++ PKTSETLINK(p, NULL); ++ PKTFREE(osh, p, dir); ++ q->len--; ++ pq->len--; ++ p = (head ? q->head : PKTLINK(prev)); ++ } else { ++ prev = p; ++ p = PKTLINK(p); ++ } ++ } ++ ++ if (q->head == NULL) { ++ ASSERT(q->len == 0); ++ q->tail = NULL; ++ } ++} ++ ++bool BCMFASTPATH ++pktq_pdel(struct pktq *pq, void *pktbuf, int prec) ++{ ++ struct pktq_prec *q; ++ void *p; ++ ++ ASSERT(prec >= 0 && prec < pq->num_prec); ++ ++ if (!pktbuf) { ++ return FALSE; ++ } ++ ++ q = &pq->q[prec]; ++ ++ if (q->head == pktbuf) { ++ if ((q->head = PKTLINK(pktbuf)) == NULL) { ++ q->tail = NULL; ++ } ++ } else { ++ for (p = q->head; p && PKTLINK(p) != pktbuf; p = PKTLINK(p)) { ++ ; ++ } ++ if (p == NULL) { ++ return FALSE; ++ } ++ ++ PKTSETLINK(p, PKTLINK(pktbuf)); ++ if (q->tail == pktbuf) { ++ q->tail = p; ++ } ++ } ++ ++ q->len--; ++ pq->len--; ++ PKTSETLINK(pktbuf, NULL); ++ return TRUE; ++} ++ ++void ++pktq_init(struct pktq *pq, int num_prec, int max_len) ++{ ++ int prec; ++ ++ ASSERT(num_prec > 0 && num_prec <= PKTQ_MAX_PREC); ++ ++ /* pq is variable size; only zero out what's requested */ ++ bzero(pq, OFFSETOF(struct pktq, q) + (sizeof(struct pktq_prec) * num_prec)); ++ ++ pq->num_prec = (uint16)num_prec; ++ ++ pq->max = (uint16)max_len; ++ ++ for (prec = 0; prec < num_prec; prec++) { ++ pq->q[prec].max = pq->max; ++ } ++} ++ ++void ++pktq_set_max_plen(struct pktq *pq, int prec, int max_len) ++{ ++ ASSERT(prec >= 0 && prec < pq->num_prec); ++ ++ if (prec < pq->num_prec) { ++ pq->q[prec].max = (uint16)max_len; ++ } ++} ++ ++void * BCMFASTPATH ++pktq_deq(struct pktq *pq, int *prec_out) ++{ ++ struct pktq_prec *q; ++ void *p; ++ int prec; ++ ++ if (pq->len == 0) { ++ return NULL; ++ } ++ ++ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) { ++ pq->hi_prec--; ++ } ++ ++ q = &pq->q[prec]; ++ ++ if ((p = q->head) == NULL) { ++ return NULL; ++ } ++ ++ if ((q->head = PKTLINK(p)) == NULL) { ++ q->tail = NULL; ++ } ++ ++ q->len--; ++ ++ pq->len--; ++ ++ if (prec_out) { ++ *prec_out = prec; ++ } ++ ++ PKTSETLINK(p, NULL); ++ ++ return p; ++} ++ ++void * BCMFASTPATH ++pktq_deq_tail(struct pktq *pq, int *prec_out) ++{ ++ struct pktq_prec *q; ++ void *p, *prev; ++ int prec; ++ ++ if (pq->len == 0) { ++ return NULL; ++ } ++ ++ for (prec = 0; prec < pq->hi_prec; prec++) { ++ if (pq->q[prec].head) { ++ break; ++ } ++ } ++ ++ q = &pq->q[prec]; ++ ++ if ((p = q->head) == NULL) { ++ return NULL; ++ } ++ ++ for (prev = NULL; p != q->tail; p = PKTLINK(p)) { ++ prev = p; ++ } ++ ++ if (prev) { ++ PKTSETLINK(prev, NULL); ++ } else { ++ q->head = NULL; ++ } ++ ++ q->tail = prev; ++ q->len--; ++ ++ pq->len--; ++ ++ if (prec_out) { ++ *prec_out = prec; ++ } ++ ++ PKTSETLINK(p, NULL); ++ ++ return p; ++} ++ ++void * ++pktq_peek(struct pktq *pq, int *prec_out) ++{ ++ int prec; ++ ++ if (pq->len == 0) { ++ return NULL; ++ } ++ ++ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) { ++ pq->hi_prec--; ++ } ++ ++ if (prec_out) { ++ *prec_out = prec; ++ } ++ ++ return (pq->q[prec].head); ++} ++ ++void * ++pktq_peek_tail(struct pktq *pq, int *prec_out) ++{ ++ int prec; ++ ++ if (pq->len == 0) { ++ return NULL; ++ } ++ ++ for (prec = 0; prec < pq->hi_prec; prec++) { ++ if (pq->q[prec].head) { ++ break; ++ } ++ } ++ ++ if (prec_out) { ++ *prec_out = prec; ++ } ++ ++ return (pq->q[prec].tail); ++} ++ ++void ++pktq_flush(osl_t *osh, struct pktq *pq, bool dir, ifpkt_cb_t fn, int arg) ++{ ++ int prec; ++ ++ /* Optimize flush, if pktq len = 0, just return. ++ * pktq len of 0 means pktq's prec q's are all empty. ++ */ ++ if (pq->len == 0) { ++ return; ++ } ++ ++ for (prec = 0; prec < pq->num_prec; prec++) { ++ pktq_pflush(osh, pq, prec, dir, fn, arg); ++ } ++ if (fn == NULL) { ++ ASSERT(pq->len == 0); ++ } ++} ++ ++/* Return sum of lengths of a specific set of precedences */ ++int ++pktq_mlen(struct pktq *pq, uint prec_bmp) ++{ ++ int prec, len; ++ ++ len = 0; ++ ++ for (prec = 0; prec <= pq->hi_prec; prec++) { ++ if (prec_bmp & (1 << prec)) { ++ len += pq->q[prec].len; ++ } ++ } ++ ++ return len; ++} ++ ++/* Priority peek from a specific set of precedences */ ++void * BCMFASTPATH ++pktq_mpeek(struct pktq *pq, uint prec_bmp, int *prec_out) ++{ ++ struct pktq_prec *q; ++ void *p; ++ int prec; ++ ++ if (pq->len == 0) { ++ return NULL; ++ } ++ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) { ++ pq->hi_prec--; ++ } ++ ++ while ((prec_bmp & (1 << prec)) == 0 || pq->q[prec].head == NULL) { ++ if (prec-- == 0) { ++ return NULL; ++ } ++ } ++ ++ q = &pq->q[prec]; ++ ++ if ((p = q->head) == NULL) { ++ return NULL; ++ } ++ ++ if (prec_out) { ++ *prec_out = prec; ++ } ++ ++ return p; ++} ++/* Priority dequeue from a specific set of precedences */ ++void * BCMFASTPATH ++pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out) ++{ ++ struct pktq_prec *q; ++ void *p; ++ int prec; ++ ++ if (pq->len == 0) { ++ return NULL; ++ } ++ ++ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) { ++ pq->hi_prec--; ++ } ++ ++ while ((pq->q[prec].head == NULL) || ((prec_bmp & (1 << prec)) == 0)) { ++ if (prec-- == 0) { ++ return NULL; ++ } ++ } ++ ++ q = &pq->q[prec]; ++ ++ if ((p = q->head) == NULL) { ++ return NULL; ++ } ++ ++ if ((q->head = PKTLINK(p)) == NULL) { ++ q->tail = NULL; ++ } ++ ++ q->len--; ++ ++ if (prec_out) { ++ *prec_out = prec; ++ } ++ ++ pq->len--; ++ ++ PKTSETLINK(p, NULL); ++ ++ return p; ++} ++ ++#endif /* BCMDRIVER */ ++ ++#if defined(BCMROMBUILD) ++const unsigned char BCMROMDATA(bcm_ctype)[] = { ++#else ++const unsigned char bcm_ctype[] = { ++#endif ++ ++ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 0-7 */ ++ _BCM_C, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C, ++ _BCM_C, /* 8-15 */ ++ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 16-23 */ ++ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 24-31 */ ++ _BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 32-39 */ ++ _BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 40-47 */ ++ _BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D, /* 48-55 */ ++ _BCM_D,_BCM_D,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 56-63 */ ++ _BCM_P, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, ++ _BCM_U|_BCM_X, _BCM_U, /* 64-71 */ ++ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 72-79 */ ++ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 80-87 */ ++ _BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 88-95 */ ++ _BCM_P, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, ++ _BCM_L|_BCM_X, _BCM_L, /* 96-103 */ ++ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 104-111 */ ++ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 112-119 */ ++ _BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_C, /* 120-127 */ ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 128-143 */ ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 144-159 */ ++ _BCM_S|_BCM_SP, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, ++ _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 160-175 */ ++ _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, ++ _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 176-191 */ ++ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, ++ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, /* 192-207 */ ++ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_P, _BCM_U, _BCM_U, _BCM_U, ++ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_L, /* 208-223 */ ++ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, ++ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, /* 224-239 */ ++ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_P, _BCM_L, _BCM_L, _BCM_L, ++ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L /* 240-255 */ ++}; ++ ++ulong ++BCMROMFN(bcm_strtoul)(const char *cp, char **endp, uint base) ++{ ++ ulong result, last_result = 0, value; ++ bool minus; ++ ++ minus = FALSE; ++ ++ while (bcm_isspace(*cp)) { ++ cp++; ++ } ++ ++ if (cp[0] == '+') { ++ cp++; ++ } else if (cp[0] == '-') { ++ minus = TRUE; ++ cp++; ++ } ++ ++ if (base == 0) { ++ if (cp[0] == '0') { ++ if ((cp[1] == 'x') || (cp[1] == 'X')) { ++ base = 16; ++ cp = &cp[2]; ++ } else { ++ base = 8; ++ cp = &cp[1]; ++ } ++ } else { ++ base = 10; ++ } ++ } else if (base == 16 && (cp[0] == '0') && ((cp[1] == 'x') || (cp[1] == 'X'))) { ++ cp = &cp[2]; ++ } ++ ++ result = 0; ++ ++ while (bcm_isxdigit(*cp) && ++ (value = bcm_isdigit(*cp) ? *cp-'0' : bcm_toupper(*cp)-'A'+10) < base) { ++ result = result*base + value; ++ /* Detected overflow */ ++ if (result < last_result && !minus) { ++ return (ulong)-1; ++ } ++ last_result = result; ++ cp++; ++ } ++ ++ if (minus) { ++ result = (ulong)(-(long)result); ++ } ++ ++ if (endp) { ++ *endp = DISCARD_QUAL(cp, char); ++ } ++ ++ return (result); ++} ++ ++int ++BCMROMFN(bcm_atoi)(const char *s) ++{ ++ return (int)bcm_strtoul(s, NULL, 10); ++} ++ ++/* return pointer to location of substring 'needle' in 'haystack' */ ++char * ++BCMROMFN(bcmstrstr)(const char *haystack, const char *needle) ++{ ++ int len, nlen; ++ int i; ++ ++ if ((haystack == NULL) || (needle == NULL)) { ++ return DISCARD_QUAL(haystack, char); ++ } ++ ++ nlen = strlen(needle); ++ len = strlen(haystack) - nlen + 1; ++ ++ for (i = 0; i < len; i++) { ++ if (memcmp(needle, &haystack[i], nlen) == 0) { ++ return DISCARD_QUAL(&haystack[i], char); ++ } ++ } ++ return (NULL); ++} ++ ++char * ++BCMROMFN(bcmstrcat)(char *dest, const char *src) ++{ ++ char *p; ++ ++ p = dest + strlen(dest); ++ ++ while ((*p++ = *src++) != '\0') { ++ ; ++ } ++ ++ return (dest); ++} ++ ++char * ++BCMROMFN(bcmstrncat)(char *dest, const char *src, uint size) ++{ ++ char *endp; ++ char *p; ++ ++ p = dest + strlen(dest); ++ endp = p + size; ++ ++ while (p != endp && (*p++ = *src++) != '\0') { ++ ; ++ } ++ ++ return (dest); ++} ++ ++ ++/**************************************************************************** ++* Function: bcmstrtok ++* ++* Purpose: ++* Tokenizes a string. This function is conceptually similiar to ANSI C strtok(), ++* but allows strToken() to be used by different strings or callers at the same ++* time. Each call modifies '*string' by substituting a NULL character for the ++* first delimiter that is encountered, and updates 'string' to point to the char ++* after the delimiter. Leading delimiters are skipped. ++* ++* Parameters: ++* string (mod) Ptr to string ptr, updated by token. ++* delimiters (in) Set of delimiter characters. ++* tokdelim (out) Character that delimits the returned token. (May ++* be set to NULL if token delimiter is not required). ++* ++* Returns: Pointer to the next token found. NULL when no more tokens are found. ++***************************************************************************** ++*/ ++char * ++bcmstrtok(char **string, const char *delimiters, char *tokdelim) ++{ ++ unsigned char *str; ++ unsigned long map[8]; ++ int count; ++ char *nextoken; ++ ++ if (tokdelim != NULL) { ++ /* Prime the token delimiter */ ++ *tokdelim = '\0'; ++ } ++ ++ /* Clear control map */ ++ for (count = 0; count < 8; count++) { ++ map[count] = 0; ++ } ++ ++ /* Set bits in delimiter table */ ++ do { ++ map[*delimiters >> 5] |= (1 << (*delimiters & 31)); ++ } ++ while (*delimiters++); ++ ++ str = (unsigned char*)*string; ++ ++ /* Find beginning of token (skip over leading delimiters). Note that ++ * there is no token iff this loop sets str to point to the terminal ++ * null (*str == '\0') ++ */ ++ while (((map[*str >> 5] & (1 << (*str & 31))) && *str) || (*str == ' ')) { ++ str++; ++ } ++ ++ nextoken = (char*)str; ++ ++ /* Find the end of the token. If it is not the end of the string, ++ * put a null there. ++ */ ++ for (; *str; str++) { ++ if (map[*str >> 5] & (1 << (*str & 31))) { ++ if (tokdelim != NULL) { ++ *tokdelim = *str; ++ } ++ ++ *str++ = '\0'; ++ break; ++ } ++ } ++ ++ *string = (char*)str; ++ ++ /* Determine if a token has been found. */ ++ if (nextoken == (char *) str) { ++ return NULL; ++ } ++ else { ++ return nextoken; ++ } ++} ++ ++ ++#define xToLower(C) \ ++ ((C >= 'A' && C <= 'Z') ? (char)((int)C - (int)'A' + (int)'a') : C) ++ ++ ++/**************************************************************************** ++* Function: bcmstricmp ++* ++* Purpose: Compare to strings case insensitively. ++* ++* Parameters: s1 (in) First string to compare. ++* s2 (in) Second string to compare. ++* ++* Returns: Return 0 if the two strings are equal, -1 if t1 < t2 and 1 if ++* t1 > t2, when ignoring case sensitivity. ++***************************************************************************** ++*/ ++int ++bcmstricmp(const char *s1, const char *s2) ++{ ++ char dc, sc; ++ ++ while (*s2 && *s1) { ++ dc = xToLower(*s1); ++ sc = xToLower(*s2); ++ if (dc < sc) return -1; ++ if (dc > sc) return 1; ++ s1++; ++ s2++; ++ } ++ ++ if (*s1 && !*s2) return 1; ++ if (!*s1 && *s2) return -1; ++ return 0; ++} ++ ++ ++/**************************************************************************** ++* Function: bcmstrnicmp ++* ++* Purpose: Compare to strings case insensitively, upto a max of 'cnt' ++* characters. ++* ++* Parameters: s1 (in) First string to compare. ++* s2 (in) Second string to compare. ++* cnt (in) Max characters to compare. ++* ++* Returns: Return 0 if the two strings are equal, -1 if t1 < t2 and 1 if ++* t1 > t2, when ignoring case sensitivity. ++***************************************************************************** ++*/ ++int ++bcmstrnicmp(const char* s1, const char* s2, int cnt) ++{ ++ char dc, sc; ++ ++ while (*s2 && *s1 && cnt) { ++ dc = xToLower(*s1); ++ sc = xToLower(*s2); ++ if (dc < sc) return -1; ++ if (dc > sc) return 1; ++ s1++; ++ s2++; ++ cnt--; ++ } ++ ++ if (!cnt) return 0; ++ if (*s1 && !*s2) return 1; ++ if (!*s1 && *s2) return -1; ++ return 0; ++} ++ ++/* parse a xx:xx:xx:xx:xx:xx format ethernet address */ ++int ++BCMROMFN(bcm_ether_atoe)(const char *p, struct ether_addr *ea) ++{ ++ int i = 0; ++ char *ep; ++ ++ for (;;) { ++ ea->octet[i++] = (char) bcm_strtoul(p, &ep, 16); ++ p = ep; ++ if (!*p++ || i == 6) ++ break; ++ } ++ ++ return (i == 6); ++} ++ ++ ++#if defined(CONFIG_USBRNDIS_RETAIL) || defined(NDIS_MINIPORT_DRIVER) ++/* registry routine buffer preparation utility functions: ++ * parameter order is like strncpy, but returns count ++ * of bytes copied. Minimum bytes copied is null char(1)/wchar(2) ++ */ ++ulong ++wchar2ascii(char *abuf, ushort *wbuf, ushort wbuflen, ulong abuflen) ++{ ++ ulong copyct = 1; ++ ushort i; ++ ++ if (abuflen == 0) ++ return 0; ++ ++ /* wbuflen is in bytes */ ++ wbuflen /= sizeof(ushort); ++ ++ for (i = 0; i < wbuflen; ++i) { ++ if (--abuflen == 0) { ++ break; ++ } ++ *abuf++ = (char) *wbuf++; ++ ++copyct; ++ } ++ *abuf = '\0'; ++ ++ return copyct; ++} ++#endif /* CONFIG_USBRNDIS_RETAIL || NDIS_MINIPORT_DRIVER */ ++ ++char * ++bcm_ether_ntoa(const struct ether_addr *ea, char *buf) ++{ ++ static const char hex[] = ++ { ++ '0', '1', '2', '3', '4', '5', '6', '7', ++ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' ++ }; ++ const uint8 *octet = ea->octet; ++ char *p = buf; ++ int i; ++ ++ for (i = 0; i < 6; i++, octet++) { ++ *p++ = hex[(*octet >> 4) & 0xf]; ++ *p++ = hex[*octet & 0xf]; ++ *p++ = ':'; ++ } ++ ++ *(p-1) = '\0'; ++ ++ return (buf); ++} ++ ++char * ++bcm_ip_ntoa(struct ipv4_addr *ia, char *buf) ++{ ++ snprintf(buf, 16, "%d.%d.%d.%d", ++ ia->addr[0], ia->addr[1], ia->addr[2], ia->addr[3]); ++ return (buf); ++} ++ ++#ifdef BCMDRIVER ++ ++void ++bcm_mdelay(uint ms) ++{ ++ uint i; ++ ++ for (i = 0; i < ms; i++) { ++ OSL_DELAY(1000); ++ } ++} ++ ++/* ++ * Search the name=value vars for a specific one and return its value. ++ * Returns NULL if not found. ++ */ ++char * ++getvar(char *vars, const char *name) ++{ ++#ifdef _MINOSL_ ++ return NULL; ++#else ++ char *s; ++ int len; ++ ++ if (!name) { ++ return NULL; ++ } ++ ++ len = strlen(name); ++ if (len == 0) { ++ return NULL; ++ } ++ ++ /* first look in vars[] */ ++ for (s = vars; s && *s;) { ++ if ((bcmp(s, name, len) == 0) && (s[len] == '=') && (strlen(s)==len)) { ++ return (&s[len+1]); ++ } ++ ++ while (*s++) { ++ ; ++ } ++ } ++ ++ /* then query nvram */ ++ return (nvram_get(name)); ++#endif /* defined(_MINOSL_) */ ++} ++ ++/* ++ * Search the vars for a specific one and return its value as ++ * an integer. Returns 0 if not found. ++ */ ++int ++getintvar(char *vars, const char *name) ++{ ++#ifdef _MINOSL_ ++ return 0; ++#else ++ char *val; ++ ++ if ((val = getvar(vars, name)) == NULL) { ++ return (0); ++ } ++ ++ return (bcm_strtoul(val, NULL, 0)); ++#endif /* _MINOSL_ */ ++} ++ ++int ++getintvararray(char *vars, const char *name, int index) ++{ ++#ifdef _MINOSL_ ++ return 0; ++#else ++ char *buf, *endp; ++ int i = 0; ++ int val = 0; ++ ++ if ((buf = getvar(vars, name)) == NULL) { ++ return (0); ++ } ++ ++ /* table values are always separated by "," or " " */ ++ while (*buf != '\0') { ++ val = bcm_strtoul(buf, &endp, 0); ++ if (i == index) { ++ return val; ++ } ++ buf = endp; ++ /* delimiter is ',' */ ++ if (*buf == ',') { ++ buf++; ++ } ++ i++; ++ } ++ return 0; ++#endif /* _MINOSL_ */ ++} ++ ++int ++getintvararraysize(char *vars, const char *name) ++{ ++#ifdef _MINOSL_ ++ return 0; ++#else ++ char *buf, *endp; ++ int count = 0; ++ int val = 0; ++ ++ if ((buf = getvar(vars, name)) == NULL) { ++ return (0); ++ } ++ ++ /* table values are always separated by "," or " " */ ++ while (*buf != '\0') { ++ val = bcm_strtoul(buf, &endp, 0); ++ buf = endp; ++ /* delimiter is ',' */ ++ if (*buf == ',') { ++ buf++; ++ } ++ count++; ++ } ++ BCM_REFERENCE(val); ++ return count; ++#endif /* _MINOSL_ */ ++} ++ ++/* Search for token in comma separated token-string */ ++static int ++findmatch(const char *string, const char *name) ++{ ++ uint len; ++ char *c; ++ ++ len = strlen(name); ++ while ((c = strchr(string, ',')) != NULL) { ++ if (len == (uint)(c - string) && !strncmp(string, name, len)) { ++ return 1; ++ } ++ string = c + 1; ++ } ++ ++ return (!strcmp(string, name)); ++} ++ ++/* Return gpio pin number assigned to the named pin ++ * ++ * Variable should be in format: ++ * ++ * gpio=pin_name,pin_name ++ * ++ * This format allows multiple features to share the gpio with mutual ++ * understanding. ++ * ++ * 'def_pin' is returned if a specific gpio is not defined for the requested functionality ++ * and if def_pin is not used by others. ++ */ ++uint ++getgpiopin(char *vars, char *pin_name, uint def_pin) ++{ ++ char name[] = "gpioXXXX"; ++ char *val; ++ uint pin; ++ ++ /* Go thru all possibilities till a match in pin name */ ++ for (pin = 0; pin < GPIO_NUMPINS; pin ++) { ++ snprintf(name, sizeof(name), "gpio%d", pin); ++ val = getvar(vars, name); ++ if (val && findmatch(val, pin_name)) { ++ return pin; ++ } ++ } ++ ++ if (def_pin != GPIO_PIN_NOTDEFINED) { ++ /* make sure the default pin is not used by someone else */ ++ snprintf(name, sizeof(name), "gpio%d", def_pin); ++ if (getvar(vars, name)) { ++ def_pin = GPIO_PIN_NOTDEFINED; ++ } ++ } ++ return def_pin; ++} ++ ++ ++/* Return the WAN port number ++ * ++ * 0 is returned if no wanport is configured. ++ */ ++int ++getwanport(void) ++{ ++ char name[] = "wanport"; ++ int retval; ++ ++ retval = getintvar(NULL, name); ++ return retval; ++} ++ ++ ++/* Return the brcmtag variable ++ * ++ * 0 is returned if no wanport is configured. ++ */ ++int ++getbrcmtag(void) ++{ ++ char name[] = "brcmtag"; ++ int retval; ++ ++ retval = getintvar(NULL, name); ++ return retval; ++} ++ ++#if defined(BCMPERFSTATS) || defined(BCMTSTAMPEDLOGS) ++#define LOGSIZE 256 /* should be power of 2 to avoid div below */ ++static struct { ++ uint cycles; ++ char *fmt; ++ uint a1; ++ uint a2; ++} logtab[LOGSIZE]; ++ ++/* last entry logged */ ++static uint logi = 0; ++/* next entry to read */ ++static uint readi = 0; ++#endif /* defined(BCMPERFSTATS) || defined(BCMTSTAMPEDLOGS) */ ++ ++#ifdef BCMPERFSTATS ++void ++bcm_perf_enable() ++{ ++ BCMPERF_ENABLE_INSTRCOUNT(); ++ BCMPERF_ENABLE_ICACHE_MISS(); ++ BCMPERF_ENABLE_ICACHE_HIT(); ++} ++ ++/* WARNING: This routine uses OSL_GETCYCLES(), which can give unexpected results on ++ * modern speed stepping CPUs. Use bcmtslog() instead in combination with TSF counter. ++ */ ++void ++bcmlog(char *fmt, uint a1, uint a2) ++{ ++ static uint last = 0; ++ uint cycles, i; ++ OSL_GETCYCLES(cycles); ++ ++ i = logi; ++ ++ logtab[i].cycles = cycles - last; ++ logtab[i].fmt = fmt; ++ logtab[i].a1 = a1; ++ logtab[i].a2 = a2; ++ ++ logi = (i + 1) % LOGSIZE; ++ last = cycles; ++} ++ ++ ++void ++bcmstats(char *fmt) ++{ ++ static uint last = 0; ++ static uint32 ic_miss = 0; ++ static uint32 instr_count = 0; ++ uint32 ic_miss_cur; ++ uint32 instr_count_cur; ++ uint cycles, i; ++ ++ OSL_GETCYCLES(cycles); ++ BCMPERF_GETICACHE_MISS(ic_miss_cur); ++ BCMPERF_GETINSTRCOUNT(instr_count_cur); ++ ++ i = logi; ++ ++ logtab[i].cycles = cycles - last; ++ logtab[i].a1 = ic_miss_cur - ic_miss; ++ logtab[i].a2 = instr_count_cur - instr_count; ++ logtab[i].fmt = fmt; ++ ++ logi = (i + 1) % LOGSIZE; ++ ++ last = cycles; ++ instr_count = instr_count_cur; ++ ic_miss = ic_miss_cur; ++} ++ ++ ++void ++bcmdumplog(char *buf, int size) ++{ ++ char *limit; ++ int j = 0; ++ int num; ++ ++ limit = buf + size - 80; ++ *buf = '\0'; ++ ++ num = logi - readi; ++ ++ if (num < 0) { ++ num += LOGSIZE; ++ } ++ ++ /* print in chronological order */ ++ ++ for (j = 0; j < num && (buf < limit); readi = (readi + 1) % LOGSIZE, j++) { ++ if (logtab[readi].fmt == NULL) { ++ continue; ++ } ++ buf += snprintf(buf, (limit - buf), "%d\t", logtab[readi].cycles); ++ buf += snprintf(buf, (limit - buf), logtab[readi].fmt, logtab[readi].a1, ++ logtab[readi].a2); ++ buf += snprintf(buf, (limit - buf), "\n"); ++ } ++ ++} ++ ++ ++/* ++ * Dump one log entry at a time. ++ * Return index of next entry or -1 when no more . ++ */ ++int ++bcmdumplogent(char *buf, uint i) ++{ ++ bool hit; ++ ++ /* ++ * If buf is NULL, return the starting index, ++ * interpreting i as the indicator of last 'i' entries to dump. ++ */ ++ if (buf == NULL) { ++ i = ((i > 0) && (i < (LOGSIZE - 1))) ? i : (LOGSIZE - 1); ++ return ((logi - i) % LOGSIZE); ++ } ++ ++ *buf = '\0'; ++ ++ ASSERT(i < LOGSIZE); ++ ++ if (i == logi) { ++ return (-1); ++ } ++ ++ hit = FALSE; ++ for (; (i != logi) && !hit; i = (i + 1) % LOGSIZE) { ++ if (logtab[i].fmt == NULL) { ++ continue; ++ } ++ buf += sprintf(buf, "%d: %d\t", i, logtab[i].cycles); ++ buf += sprintf(buf, logtab[i].fmt, logtab[i].a1, logtab[i].a2); ++ buf += sprintf(buf, "\n"); ++ hit = TRUE; ++ } ++ ++ return (i); ++} ++ ++#endif /* BCMPERFSTATS */ ++ ++#if defined(BCMTSTAMPEDLOGS) ++/* Store a TSF timestamp and a log line in the log buffer */ ++void ++bcmtslog(uint32 tstamp, char *fmt, uint a1, uint a2) ++{ ++ uint i = logi; ++ bool use_delta = FALSE; ++ static uint32 last = 0; /* used only when use_delta is true */ ++ ++ logtab[i].cycles = tstamp; ++ if (use_delta) { ++ logtab[i].cycles -= last; ++ } ++ ++ logtab[i].fmt = fmt; ++ logtab[i].a1 = a1; ++ logtab[i].a2 = a2; ++ ++ if (use_delta) { ++ last = tstamp; ++ } ++ logi = (i + 1) % LOGSIZE; ++} ++ ++/* Print out a microsecond timestamp as "sec.ms.us " */ ++void ++bcmprinttstamp(uint32 ticks) ++{ ++ uint us, ms, sec; ++ ++ us = (ticks % TSF_TICKS_PER_MS) * 1000 / TSF_TICKS_PER_MS; ++ ms = ticks / TSF_TICKS_PER_MS; ++ sec = ms / 1000; ++ ms -= sec * 1000; ++ printf("%04u.%03u.%03u ", sec, ms, us); ++} ++ ++/* Print out the log buffer with timestamps */ ++void ++bcmprinttslogs(void) ++{ ++ int j = 0; ++ int num; ++ ++ num = logi - readi; ++ if (num < 0) { ++ num += LOGSIZE; ++ } ++ ++ /* Format and print the log entries directly in chronological order */ ++ for (j = 0; j < num; readi = (readi + 1) % LOGSIZE, j++) { ++ if (logtab[readi].fmt == NULL) { ++ continue; ++ } ++ bcmprinttstamp(logtab[readi].cycles); ++ printf(logtab[readi].fmt, logtab[readi].a1, logtab[readi].a2); ++ printf("\n"); ++ } ++} ++ ++void ++bcmdumptslog(char *buf, int size) ++{ ++ char *limit; ++ int j = 0; ++ int num; ++ uint us, ms, sec; ++ ++ limit = buf + size - 80; ++ *buf = '\0'; ++ ++ num = logi - readi; ++ ++ if (num < 0) { ++ num += LOGSIZE; ++ } ++ ++ /* print in chronological order */ ++ for (j = 0; j < num && (buf < limit); readi = (readi + 1) % LOGSIZE, j++) { ++ if (logtab[readi].fmt == NULL) { ++ continue; ++ } ++ us = (logtab[readi].cycles % TSF_TICKS_PER_MS) * 1000 / TSF_TICKS_PER_MS; ++ ms = logtab[readi].cycles / TSF_TICKS_PER_MS; ++ sec = ms / 1000; ++ ms -= sec * 1000; ++ ++ buf += snprintf(buf, (limit - buf), "%04u.%03u.%03u ", sec, ms, us); ++ /* buf += snprintf(buf, (limit - buf), "%d\t", logtab[readi].cycles); */ ++ buf += snprintf(buf, (limit - buf), logtab[readi].fmt, logtab[readi].a1, ++ logtab[readi].a2); ++ buf += snprintf(buf, (limit - buf), "\n"); ++ } ++} ++#endif /* BCMTSTAMPEDLOGS */ ++ ++#if defined(BCMDBG) || defined(DHD_DEBUG) ++/* pretty hex print a pkt buffer chain */ ++void ++prpkt(const char *msg, osl_t *osh, void *p0) ++{ ++ void *p; ++ ++ if (msg && (msg[0] != '\0')) { ++ printf("%s:\n", msg); ++ } ++ ++ for (p = p0; p; p = PKTNEXT(osh, p)) { ++ prhex(NULL, PKTDATA(osh, p), PKTLEN(osh, p)); ++ } ++} ++#endif /* BCMDBG || DHD_DEBUG */ ++ ++/* Takes an Ethernet frame and sets out-of-bound PKTPRIO. ++ * Also updates the inplace vlan tag if requested. ++ * For debugging, it returns an indication of what it did. ++ */ ++uint BCMFASTPATH ++pktsetprio(void *pkt, bool update_vtag) ++{ ++ struct ether_header *eh; ++ struct ethervlan_header *evh; ++ uint8 *pktdata; ++ int priority = 0; ++ int rc = 0; ++ ++ pktdata = (uint8 *)PKTDATA(NULL, pkt); ++ ASSERT(ISALIGNED((uintptr)pktdata, sizeof(uint16))); ++ ++ eh = (struct ether_header *) pktdata; ++ ++ if (eh->ether_type == hton16(ETHER_TYPE_8021Q)) { ++ uint16 vlan_tag; ++ int vlan_prio, dscp_prio = 0; ++ ++ evh = (struct ethervlan_header *)eh; ++ ++ vlan_tag = ntoh16(evh->vlan_tag); ++ vlan_prio = (int) (vlan_tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK; ++ ++ if (evh->ether_type == hton16(ETHER_TYPE_IP)) { ++ uint8 *ip_body = pktdata + sizeof(struct ethervlan_header); ++ uint8 tos_tc = IP_TOS46(ip_body); ++ dscp_prio = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT); ++ } ++ ++ /* DSCP priority gets precedence over 802.1P (vlan tag) */ ++ if (dscp_prio != 0) { ++ priority = dscp_prio; ++ rc |= PKTPRIO_VDSCP; ++ } else { ++ priority = vlan_prio; ++ rc |= PKTPRIO_VLAN; ++ } ++ /* ++ * If the DSCP priority is not the same as the VLAN priority, ++ * then overwrite the priority field in the vlan tag, with the ++ * DSCP priority value. This is required for Linux APs because ++ * the VLAN driver on Linux, overwrites the skb->priority field ++ * with the priority value in the vlan tag ++ */ ++ if (update_vtag && (priority != vlan_prio)) { ++ vlan_tag &= ~(VLAN_PRI_MASK << VLAN_PRI_SHIFT); ++ vlan_tag |= (uint16)priority << VLAN_PRI_SHIFT; ++ evh->vlan_tag = hton16(vlan_tag); ++ rc |= PKTPRIO_UPD; ++ } ++ } else if (eh->ether_type == hton16(ETHER_TYPE_IP)) { ++ uint8 *ip_body = pktdata + sizeof(struct ether_header); ++ uint8 tos_tc = IP_TOS46(ip_body); ++ priority = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT); ++ rc |= PKTPRIO_DSCP; ++ } ++ ++ ASSERT(priority >= 0 && priority <= MAXPRIO); ++ PKTSETPRIO(pkt, priority); ++ return (rc | priority); ++} ++ ++#ifndef BCM_BOOTLOADER ++ ++static char bcm_undeferrstr[32]; ++static const char *const bcmerrorstrtable[] = BCMERRSTRINGTABLE; ++ ++/* Convert the error codes into related error strings */ ++const char * ++bcmerrorstr(int bcmerror) ++{ ++ /* check if someone added a bcmerror code but forgot to add errorstring */ ++ ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(bcmerrorstrtable) - 1)); ++ ++ if (bcmerror > 0 || bcmerror < BCME_LAST) { ++ snprintf(bcm_undeferrstr, sizeof(bcm_undeferrstr), "Undefined error %d", bcmerror); ++ return bcm_undeferrstr; ++ } ++ ++ ASSERT(strlen(bcmerrorstrtable[-bcmerror]) < BCME_STRLEN); ++ ++ return bcmerrorstrtable[-bcmerror]; ++} ++ ++#endif /* !BCM_BOOTLOADER */ ++ ++#ifdef WLC_LOW ++static void ++BCMINITFN(bcm_nvram_refresh)(char *flash) ++{ ++ int i; ++ int ret = 0; ++ ++ ASSERT(flash != NULL); ++ ++ /* default "empty" vars cache */ ++ bzero(flash, 2); ++ ++ if ((ret = nvram_getall(flash, NVRAM_SPACE))) { ++ return; ++ } ++ ++ /* determine nvram length */ ++ for (i = 0; i < NVRAM_SPACE; i++) { ++ if (flash[i] == '\0' && flash[i+1] == '\0') { ++ break; ++ } ++ } ++ ++ if (i > 1) { ++ vars_len = i + 2; ++ } else { ++ vars_len = 0; ++ } ++} ++ ++char * ++bcm_nvram_vars(uint *length) ++{ ++ /* cache may be stale if nvram is read/write */ ++ if (nvram_vars) { ++ ASSERT(!bcmreclaimed); ++ bcm_nvram_refresh(nvram_vars); ++ } ++ if (length) { ++ *length = vars_len; ++ } ++ return nvram_vars; ++} ++ ++/* copy nvram vars into locally-allocated multi-string array */ ++int ++BCMINITFN(bcm_nvram_cache)(void *sih) ++{ ++ int ret = 0; ++ void *osh; ++ char *flash = NULL; ++ ++ if (vars_len >= 0) { ++ bcm_nvram_refresh(nvram_vars); ++ return 0; ++ } ++ ++ osh = si_osh((si_t *)sih); ++ ++ /* allocate memory and read in flash */ ++ if (!(flash = MALLOC(osh, NVRAM_SPACE))) { ++ ret = BCME_NOMEM; ++ goto exit; ++ } ++ ++ bcm_nvram_refresh(flash); ++ ++ /* cache must be full size of nvram if read/write */ ++ nvram_vars = flash; ++ ++exit: ++ return ret; ++} ++#endif /* WLC_LOW */ ++ ++ ++int32 ++exthdr_validate(char *ptr, uint size) ++{ ++ char *exthdr, *trx_offset; ++ uint hdrsz; ++ int trxof = 0; ++ ++ if ((exthdr = nvram_get("ext_imghdr"))) { ++ char s[] = "XXX"; ++ uint i, j; ++ ++ hdrsz = strlen(exthdr); ++ ++ if (hdrsz > size) { ++ printf("Exthdr_size(%d) > Image_size(%d)\n", hdrsz, size); ++ trxof = -1; ++ goto done; ++ } ++ ++ if (hdrsz == 0) { ++ goto match; ++ } ++ ++ for (i = 0, j = 0; i < (hdrsz >> 1); i++) { ++ sprintf(s, "%02x", (ptr[i] & 0xff)); ++ if ((exthdr[j++] != s[0]) || (exthdr[j++] != s[1])) { ++ printf("Header mismatch\n"); ++ goto done; ++ } ++ } ++ } ++ ++match: ++ if ((trx_offset = nvram_get("trx_offset"))) ++ trxof = bcm_strtoul(trx_offset, NULL, 0); ++ ++done: ++ return trxof; ++} ++ ++/* iovar table lookup */ ++const bcm_iovar_t* ++bcm_iovar_lookup(const bcm_iovar_t *table, const char *name) ++{ ++ const bcm_iovar_t *vi; ++ const char *lookup_name; ++ ++ /* skip any ':' delimited option prefixes */ ++ lookup_name = strrchr(name, ':'); ++ if (lookup_name != NULL) { ++ lookup_name++; ++ } else { ++ lookup_name = name; ++ } ++ ++ ASSERT(table != NULL); ++ ++ for (vi = table; vi->name; vi++) { ++ if (!strcmp(vi->name, lookup_name)) { ++ return vi; ++ } ++ } ++ /* ran to end of table */ ++ ++ return NULL; /* var name not found */ ++} ++ ++int ++bcm_iovar_lencheck(const bcm_iovar_t *vi, void *arg, int len, bool set) ++{ ++ int bcmerror = 0; ++ ++ /* length check on io buf */ ++ switch (vi->type) { ++ case IOVT_BOOL: ++ case IOVT_INT8: ++ case IOVT_INT16: ++ case IOVT_INT32: ++ case IOVT_UINT8: ++ case IOVT_UINT16: ++ case IOVT_UINT32: ++ /* all integers are int32 sized args at the ioctl interface */ ++ if (len < (int)sizeof(int)) { ++ bcmerror = BCME_BUFTOOSHORT; ++ } ++ break; ++ ++ case IOVT_BUFFER: ++ /* buffer must meet minimum length requirement */ ++ if (len < vi->minlen) { ++ bcmerror = BCME_BUFTOOSHORT; ++ } ++ break; ++ ++ case IOVT_VOID: ++ if (!set) { ++ /* Cannot return nil... */ ++ bcmerror = BCME_UNSUPPORTED; ++ } else if (len) { ++ /* Set is an action w/o parameters */ ++ bcmerror = BCME_BUFTOOLONG; ++ } ++ break; ++ ++ default: ++ /* unknown type for length check in iovar info */ ++ ASSERT(0); ++ bcmerror = BCME_UNSUPPORTED; ++ } ++ ++ return bcmerror; ++} ++#endif /* BCMDRIVER */ ++ ++ ++/******************************************************************************* ++ * crc8 ++ * ++ * Computes a crc8 over the input data using the polynomial: ++ * ++ * x^8 + x^7 +x^6 + x^4 + x^2 + 1 ++ * ++ * The caller provides the initial value (either CRC8_INIT_VALUE ++ * or the previous returned value) to allow for processing of ++ * discontiguous blocks of data. When generating the CRC the ++ * caller is responsible for complementing the final return value ++ * and inserting it into the byte stream. When checking, a final ++ * return value of CRC8_GOOD_VALUE indicates a valid CRC. ++ * ++ * Reference: Dallas Semiconductor Application Note 27 ++ * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms", ++ * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd., ++ * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt ++ * ++ * **************************************************************************** ++ */ ++ ++static const uint8 crc8_table[256] = { ++ 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B, ++ 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21, ++ 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF, ++ 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5, ++ 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14, ++ 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E, ++ 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80, ++ 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA, ++ 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95, ++ 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF, ++ 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01, ++ 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B, ++ 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA, ++ 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0, ++ 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E, ++ 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34, ++ 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0, ++ 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A, ++ 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54, ++ 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E, ++ 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF, ++ 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5, ++ 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B, ++ 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61, ++ 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E, ++ 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74, ++ 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA, ++ 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0, ++ 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41, ++ 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B, ++ 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5, ++ 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F ++}; ++ ++#define CRC_INNER_LOOP(n, c, x) \ ++ (c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff] ++ ++uint8 ++BCMROMFN(hndcrc8)( ++ uint8 *pdata, /* pointer to array of data to process */ ++ uint nbytes, /* number of input data bytes to process */ ++ uint8 crc /* either CRC8_INIT_VALUE or previous return value */ ++) ++{ ++ /* hard code the crc loop instead of using CRC_INNER_LOOP macro ++ * to avoid the undefined and unnecessary (uint8 >> 8) operation. ++ */ ++ while (nbytes-- > 0) { ++ crc = crc8_table[(crc ^ *pdata++) & 0xff]; ++ } ++ ++ return crc; ++} ++ ++/******************************************************************************* ++ * crc16 ++ * ++ * Computes a crc16 over the input data using the polynomial: ++ * ++ * x^16 + x^12 +x^5 + 1 ++ * ++ * The caller provides the initial value (either CRC16_INIT_VALUE ++ * or the previous returned value) to allow for processing of ++ * discontiguous blocks of data. When generating the CRC the ++ * caller is responsible for complementing the final return value ++ * and inserting it into the byte stream. When checking, a final ++ * return value of CRC16_GOOD_VALUE indicates a valid CRC. ++ * ++ * Reference: Dallas Semiconductor Application Note 27 ++ * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms", ++ * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd., ++ * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt ++ * ++ * **************************************************************************** ++ */ ++ ++static const uint16 crc16_table[256] = { ++ 0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF, ++ 0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7, ++ 0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E, ++ 0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876, ++ 0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD, ++ 0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5, ++ 0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C, ++ 0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974, ++ 0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB, ++ 0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3, ++ 0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A, ++ 0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72, ++ 0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9, ++ 0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1, ++ 0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738, ++ 0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70, ++ 0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7, ++ 0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF, ++ 0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036, ++ 0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E, ++ 0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5, ++ 0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD, ++ 0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134, ++ 0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C, ++ 0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3, ++ 0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB, ++ 0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232, ++ 0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A, ++ 0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1, ++ 0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9, ++ 0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330, ++ 0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78 ++}; ++ ++uint16 ++BCMROMFN(hndcrc16)( ++ uint8 *pdata, /* pointer to array of data to process */ ++ uint nbytes, /* number of input data bytes to process */ ++ uint16 crc /* either CRC16_INIT_VALUE or previous return value */ ++) ++{ ++ while (nbytes-- > 0) { ++ CRC_INNER_LOOP(16, crc, *pdata++); ++ } ++ return crc; ++} ++ ++static const uint32 crc32_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 ++}; ++ ++/* ++ * crc input is CRC32_INIT_VALUE for a fresh start, or previous return value if ++ * accumulating over multiple pieces. ++ */ ++uint32 ++BCMROMFN(hndcrc32)(uint8 *pdata, uint nbytes, uint32 crc) ++{ ++ uint8 *pend; ++#ifdef __mips__ ++ uint8 tmp[4]; ++ ulong *tptr = (ulong *)tmp; ++ ++ if (nbytes > 3) { ++ /* in case the beginning of the buffer isn't aligned */ ++ pend = (uint8 *)((uint)(pdata + 3) & ~0x3); ++ nbytes -= (pend - pdata); ++ while (pdata < pend) { ++ CRC_INNER_LOOP(32, crc, *pdata++); ++ } ++ } ++ ++ if (nbytes > 3) { ++ /* handle bulk of data as 32-bit words */ ++ pend = pdata + (nbytes & ~0x3); ++ while (pdata < pend) { ++ *tptr = *(ulong *)pdata; ++ pdata += sizeof(ulong *); ++ CRC_INNER_LOOP(32, crc, tmp[0]); ++ CRC_INNER_LOOP(32, crc, tmp[1]); ++ CRC_INNER_LOOP(32, crc, tmp[2]); ++ CRC_INNER_LOOP(32, crc, tmp[3]); ++ } ++ } ++ ++ /* 1-3 bytes at end of buffer */ ++ pend = pdata + (nbytes & 0x03); ++ while (pdata < pend) { ++ CRC_INNER_LOOP(32, crc, *pdata++); ++ } ++#else ++ pend = pdata + nbytes; ++ while (pdata < pend) { ++ CRC_INNER_LOOP(32, crc, *pdata++); ++ } ++#endif /* __mips__ */ ++ ++ return crc; ++} ++ ++#ifdef notdef ++#define CLEN 1499 /* CRC Length */ ++#define CBUFSIZ (CLEN+4) ++#define CNBUFS 5 /* # of bufs */ ++ ++void ++testcrc32(void) ++{ ++ uint j, k, l; ++ uint8 *buf; ++ uint len[CNBUFS]; ++ uint32 crcr; ++ uint32 crc32tv[CNBUFS] = ++ {0xd2cb1faa, 0xd385c8fa, 0xf5b4f3f3, 0x55789e20, 0x00343110}; ++ ++ ASSERT((buf = MALLOC(CBUFSIZ*CNBUFS)) != NULL); ++ ++ /* step through all possible alignments */ ++ for (l = 0; l <= 4; l++) { ++ for (j = 0; j < CNBUFS; j++) { ++ len[j] = CLEN; ++ for (k = 0; k < len[j]; k++) { ++ *(buf + j*CBUFSIZ + (k+l)) = (j+k) & 0xff; ++ } ++ } ++ ++ for (j = 0; j < CNBUFS; j++) { ++ crcr = crc32(buf + j*CBUFSIZ + l, len[j], CRC32_INIT_VALUE); ++ ASSERT(crcr == crc32tv[j]); ++ } ++ } ++ ++ MFREE(buf, CBUFSIZ*CNBUFS); ++ return; ++} ++#endif /* notdef */ ++ ++/* ++ * Advance from the current 1-byte tag/1-byte length/variable-length value ++ * triple, to the next, returning a pointer to the next. ++ * If the current or next TLV is invalid (does not fit in given buffer length), ++ * NULL is returned. ++ * *buflen is not modified if the TLV elt parameter is invalid, or is decremented ++ * by the TLV parameter's length if it is valid. ++ */ ++bcm_tlv_t * ++BCMROMFN(bcm_next_tlv)(bcm_tlv_t *elt, int *buflen) ++{ ++ int len; ++ ++ /* validate current elt */ ++ if (!bcm_valid_tlv(elt, *buflen)) { ++ return NULL; ++ } ++ ++ /* advance to next elt */ ++ len = elt->len; ++ elt = (bcm_tlv_t*)(elt->data + len); ++ *buflen -= (TLV_HDR_LEN + len); ++ ++ /* validate next elt */ ++ if (!bcm_valid_tlv(elt, *buflen)) { ++ return NULL; ++ } ++ ++ return elt; ++} ++ ++/* ++ * Traverse a string of 1-byte tag/1-byte length/variable-length value ++ * triples, returning a pointer to the substring whose first element ++ * matches tag ++ */ ++bcm_tlv_t * ++BCMROMFN(bcm_parse_tlvs)(void *buf, int buflen, uint key) ++{ ++ bcm_tlv_t *elt; ++ int totlen; ++ ++ elt = (bcm_tlv_t*)buf; ++ totlen = buflen; ++ ++ /* find tagged parameter */ ++ while (totlen >= TLV_HDR_LEN) { ++ int len = elt->len; ++ ++ /* validate remaining totlen */ ++ if ((elt->id == key) && ++ (totlen >= (len + TLV_HDR_LEN))) { ++ return (elt); ++ } ++ ++ elt = (bcm_tlv_t*)((uint8*)elt + (len + TLV_HDR_LEN)); ++ totlen -= (len + TLV_HDR_LEN); ++ } ++ ++ return NULL; ++} ++ ++/* ++ * Traverse a string of 1-byte tag/1-byte length/variable-length value ++ * triples, returning a pointer to the substring whose first element ++ * matches tag. Stop parsing when we see an element whose ID is greater ++ * than the target key. ++ */ ++bcm_tlv_t * ++BCMROMFN(bcm_parse_ordered_tlvs)(void *buf, int buflen, uint key) ++{ ++ bcm_tlv_t *elt; ++ int totlen; ++ ++ elt = (bcm_tlv_t*)buf; ++ totlen = buflen; ++ ++ /* find tagged parameter */ ++ while (totlen >= TLV_HDR_LEN) { ++ uint id = elt->id; ++ int len = elt->len; ++ ++ /* Punt if we start seeing IDs > than target key */ ++ if (id > key) { ++ return (NULL); ++ } ++ ++ /* validate remaining totlen */ ++ if ((id == key) && ++ (totlen >= (len + TLV_HDR_LEN))) { ++ return (elt); ++ } ++ ++ elt = (bcm_tlv_t*)((uint8*)elt + (len + TLV_HDR_LEN)); ++ totlen -= (len + TLV_HDR_LEN); ++ } ++ return NULL; ++} ++ ++#if defined(BCMDBG) || defined(BCMDBG_ERR) || defined(WLMSG_PRHDRS) || \ ++ defined(WLMSG_PRPKT) || defined(WLMSG_ASSOC) || defined(DHD_DEBUG) ++int ++bcm_format_flags(const bcm_bit_desc_t *bd, uint32 flags, char* buf, int len) ++{ ++ int i; ++ char* p = buf; ++ char hexstr[16]; ++ int slen = 0, nlen = 0; ++ uint32 bit; ++ const char* name; ++ ++ if (len < 2 || !buf) { ++ return 0; ++ } ++ ++ buf[0] = '\0'; ++ ++ for (i = 0; flags != 0; i++) { ++ bit = bd[i].bit; ++ name = bd[i].name; ++ if (bit == 0 && flags != 0) { ++ /* print any unnamed bits */ ++ snprintf(hexstr, 16, "0x%X", flags); ++ name = hexstr; ++ flags = 0; /* exit loop */ ++ } else if ((flags & bit) == 0) { ++ continue; ++ } ++ flags &= ~bit; ++ nlen = strlen(name); ++ slen += nlen; ++ /* count btwn flag space */ ++ if (flags != 0) { ++ slen += 1; ++ } ++ /* need NULL char as well */ ++ if (len <= slen) { ++ break; ++ } ++ /* copy NULL char but don't count it */ ++ strncpy(p, name, nlen + 1); ++ p += nlen; ++ /* copy btwn flag space and NULL char */ ++ if (flags != 0) { ++ p += snprintf(p, 2, " "); ++ } ++ } ++ ++ /* indicate the str was too short */ ++ if (flags != 0) { ++ if (len < 2) { ++ p -= 2 - len; /* overwrite last char */ ++ } ++ p += snprintf(p, 2, ">"); ++ } ++ ++ return (int)(p - buf); ++} ++ ++/* print bytes formatted as hex to a string. return the resulting string length */ ++int ++bcm_format_hex(char *str, const void *bytes, int len) ++{ ++ int i; ++ char *p = str; ++ const uint8 *src = (const uint8*)bytes; ++ ++ for (i = 0; i < len; i++) { ++ p += snprintf(p, 3, "%02X", *src); ++ src++; ++ } ++ return (int)(p - str); ++} ++#endif ++ ++/* pretty hex print a contiguous buffer */ ++void ++prhex(const char *msg, uchar *buf, uint nbytes) ++{ ++ char line[128], *p; ++ int len = sizeof(line); ++ int nchar; ++ uint i; ++ ++ if (msg && (msg[0] != '\0')) { ++ printf("%s:\n", msg); ++ } ++ ++ p = line; ++ for (i = 0; i < nbytes; i++) { ++ if (i % 16 == 0) { ++ nchar = snprintf(p, len, " %04d: ", i); /* line prefix */ ++ p += nchar; ++ len -= nchar; ++ } ++ if (len > 0) { ++ nchar = snprintf(p, len, "%02x ", buf[i]); ++ p += nchar; ++ len -= nchar; ++ } ++ ++ if (i % 16 == 15) { ++ printf("%s\n", line); /* flush line */ ++ p = line; ++ len = sizeof(line); ++ } ++ } ++ ++ /* flush last partial line */ ++ if (p != line) { ++ printf("%s\n", line); ++ } ++} ++ ++static const char *crypto_algo_names[] = { ++ "NONE", ++ "WEP1", ++ "TKIP", ++ "WEP128", ++ "AES_CCM", ++ "AES_OCB_MSDU", ++ "AES_OCB_MPDU", ++ "NALG" ++ "UNDEF", ++ "UNDEF", ++ "UNDEF", ++ "UNDEF" ++}; ++ ++const char * ++bcm_crypto_algo_name(uint algo) ++{ ++ return (algo < ARRAYSIZE(crypto_algo_names)) ? crypto_algo_names[algo] : "ERR"; ++} ++ ++#ifdef BCMDBG ++void ++deadbeef(void *p, size_t len) ++{ ++ static uint8 meat[] = { 0xde, 0xad, 0xbe, 0xef }; ++ ++ while (len-- > 0) { ++ *(uint8*)p = meat[((uintptr)p) & 3]; ++ p = (uint8*)p + 1; ++ } ++} ++#endif /* BCMDBG */ ++ ++char * ++bcm_chipname(uint chipid, char *buf, uint len) ++{ ++ const char *fmt; ++ ++ fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x"; ++ snprintf(buf, len, fmt, chipid); ++ return buf; ++} ++ ++/* Produce a human-readable string for boardrev */ ++char * ++bcm_brev_str(uint32 brev, char *buf) ++{ ++ if (brev < 0x100) { ++ snprintf(buf, 8, "%d.%d", (brev & 0xf0) >> 4, brev & 0xf); ++ } else { ++ snprintf(buf, 8, "%c%03x", ((brev & 0xf000) == 0x1000) ? 'P' : 'A', brev & 0xfff); ++ } ++ return (buf); ++} ++ ++#define BUFSIZE_TODUMP_ATONCE 512 /* Buffer size */ ++ ++/* dump large strings to console */ ++void ++printbig(char *buf) ++{ ++ uint len, max_len; ++ char c; ++ ++ len = strlen(buf); ++ ++ max_len = BUFSIZE_TODUMP_ATONCE; ++ ++ while (len > max_len) { ++ c = buf[max_len]; ++ buf[max_len] = '\0'; ++ printf("%s", buf); ++ buf[max_len] = c; ++ ++ buf += max_len; ++ len -= max_len; ++ } ++ /* print the remaining string */ ++ printf("%s\n", buf); ++ return; ++} ++ ++/* routine to dump fields in a fileddesc structure */ ++uint ++bcmdumpfields(bcmutl_rdreg_rtn read_rtn, void *arg0, uint arg1, struct fielddesc *fielddesc_array, ++ char *buf, uint32 bufsize) ++{ ++ uint filled_len; ++ int len; ++ struct fielddesc *cur_ptr; ++ ++ filled_len = 0; ++ cur_ptr = fielddesc_array; ++ ++ while (bufsize > 1) { ++ if (cur_ptr->nameandfmt == NULL) { ++ break; ++ } ++ len = snprintf(buf, bufsize, cur_ptr->nameandfmt, ++ read_rtn(arg0, arg1, cur_ptr->offset)); ++ /* check for snprintf overflow or error */ ++ if (len < 0 || (uint32)len >= bufsize) { ++ len = bufsize - 1; ++ } ++ buf += len; ++ bufsize -= len; ++ filled_len += len; ++ cur_ptr++; ++ } ++ return filled_len; ++} ++ ++uint ++bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen) ++{ ++ uint len; ++ ++ len = strlen(name) + 1; ++ ++ if ((len + datalen) > buflen) { ++ return 0; ++ } ++ ++ strncpy(buf, name, buflen); ++ ++ /* append data onto the end of the name string */ ++ memcpy(&buf[len], data, datalen); ++ len += datalen; ++ ++ return len; ++} ++ ++/* Quarter dBm units to mW ++ * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153 ++ * Table is offset so the last entry is largest mW value that fits in ++ * a uint16. ++ */ ++ ++#define QDBM_OFFSET 153 /* Offset for first entry */ ++#define QDBM_TABLE_LEN 40 /* Table size */ ++ ++/* Smallest mW value that will round up to the first table entry, QDBM_OFFSET. ++ * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2 ++ */ ++#define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */ ++ ++/* Largest mW value that will round down to the last table entry, ++ * QDBM_OFFSET + QDBM_TABLE_LEN-1. ++ * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) + mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2. ++ */ ++#define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */ ++ ++static const uint16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = { ++/* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */ ++/* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000, ++/* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849, ++/* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119, ++/* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811, ++/* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096 ++}; ++ ++uint16 ++BCMROMFN(bcm_qdbm_to_mw)(uint8 qdbm) ++{ ++ uint factor = 1; ++ int idx = qdbm - QDBM_OFFSET; ++ ++ if (idx >= QDBM_TABLE_LEN) { ++ /* clamp to max uint16 mW value */ ++ return 0xFFFF; ++ } ++ ++ /* scale the qdBm index up to the range of the table 0-40 ++ * where an offset of 40 qdBm equals a factor of 10 mW. ++ */ ++ while (idx < 0) { ++ idx += 40; ++ factor *= 10; ++ } ++ ++ /* return the mW value scaled down to the correct factor of 10, ++ * adding in factor/2 to get proper rounding. ++ */ ++ return ((nqdBm_to_mW_map[idx] + factor/2) / factor); ++} ++ ++uint8 ++BCMROMFN(bcm_mw_to_qdbm)(uint16 mw) ++{ ++ uint8 qdbm; ++ int offset; ++ uint mw_uint = mw; ++ uint boundary; ++ ++ /* handle boundary case */ ++ if (mw_uint <= 1) { ++ return 0; ++ } ++ ++ offset = QDBM_OFFSET; ++ ++ /* move mw into the range of the table */ ++ while (mw_uint < QDBM_TABLE_LOW_BOUND) { ++ mw_uint *= 10; ++ offset -= 40; ++ } ++ ++ for (qdbm = 0; qdbm < QDBM_TABLE_LEN-1; qdbm++) { ++ boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm+1] - ++ nqdBm_to_mW_map[qdbm])/2; ++ if (mw_uint < boundary) break; ++ } ++ ++ qdbm += (uint8)offset; ++ ++ return (qdbm); ++} ++ ++ ++uint ++BCMROMFN(bcm_bitcount)(uint8 *bitmap, uint length) ++{ ++ uint bitcount = 0, i; ++ uint8 tmp; ++ for (i = 0; i < length; i++) { ++ tmp = bitmap[i]; ++ while (tmp) { ++ bitcount++; ++ tmp &= (tmp - 1); ++ } ++ } ++ return bitcount; ++} ++ ++#ifdef BCMDRIVER ++ ++/* Initialization of bcmstrbuf structure */ ++void ++bcm_binit(struct bcmstrbuf *b, char *buf, uint size) ++{ ++ b->origsize = b->size = size; ++ b->origbuf = b->buf = buf; ++} ++ ++/* Buffer sprintf wrapper to guard against buffer overflow */ ++int ++bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...) ++{ ++ va_list ap; ++ int r; ++ ++ va_start(ap, fmt); ++ ++ r = vsnprintf(b->buf, b->size, fmt, ap); ++ ++ /* Non Ansi C99 compliant returns -1, ++ * Ansi compliant return r >= b->size, ++ * bcmstdlib returns 0, handle all ++ */ ++ /* r == 0 is also the case when strlen(fmt) is zero. ++ * typically the case when "" is passed as argument. ++ */ ++ if ((r == -1) || (r >= (int)b->size)) { ++ b->size = 0; ++ } else { ++ b->size -= r; ++ b->buf += r; ++ } ++ ++ va_end(ap); ++ ++ return r; ++} ++ ++void ++bcm_bprhex(struct bcmstrbuf *b, const char *msg, bool newline, uint8 *buf, int len) ++{ ++ int i; ++ ++ if (msg != NULL && msg[0] != '\0') { ++ bcm_bprintf(b, "%s", msg); ++ } ++ for (i = 0; i < len; i ++) { ++ bcm_bprintf(b, "%02X", buf[i]); ++ } ++ if (newline) { ++ bcm_bprintf(b, "\n"); ++ } ++} ++ ++void ++bcm_inc_bytes(uchar *num, int num_bytes, uint8 amount) ++{ ++ int i; ++ ++ for (i = 0; i < num_bytes; i++) { ++ num[i] += amount; ++ if (num[i] >= amount) { ++ break; ++ } ++ amount = 1; ++ } ++} ++ ++int ++bcm_cmp_bytes(const uchar *arg1, const uchar *arg2, uint8 nbytes) ++{ ++ int i; ++ ++ for (i = nbytes - 1; i >= 0; i--) { ++ if (arg1[i] != arg2[i]) { ++ return (arg1[i] - arg2[i]); ++ } ++ } ++ return 0; ++} ++ ++void ++bcm_print_bytes(const char *name, const uchar *data, int len) ++{ ++ int i; ++ int per_line = 0; ++ ++ printf("%s: %d \n", name ? name : "", len); ++ for (i = 0; i < len; i++) { ++ printf("%02x ", *data++); ++ per_line++; ++ if (per_line == 16) { ++ per_line = 0; ++ printf("\n"); ++ } ++ } ++ printf("\n"); ++} ++#if defined(WLTINYDUMP) || defined(BCMDBG) || defined(WLMSG_INFORM) || \ ++ defined(WLMSG_ASSOC) || defined(WLMSG_PRPKT) || defined(WLMSG_WSEC) ++#define SSID_FMT_BUF_LEN ((4 * DOT11_MAX_SSID_LEN) + 1) ++ ++int ++bcm_format_ssid(char* buf, const uchar ssid[], uint ssid_len) ++{ ++ uint i, c; ++ char *p = buf; ++ char *endp = buf + SSID_FMT_BUF_LEN; ++ ++ if (ssid_len > DOT11_MAX_SSID_LEN) { ++ ssid_len = DOT11_MAX_SSID_LEN; ++ } ++ ++ for (i = 0; i < ssid_len; i++) { ++ c = (uint)ssid[i]; ++ if (c == '\\') { ++ *p++ = '\\'; ++ *p++ = '\\'; ++ } else if (bcm_isprint((uchar)c)) { ++ *p++ = (char)c; ++ } else { ++ p += snprintf(p, (endp - p), "\\x%02X", c); ++ } ++ } ++ *p = '\0'; ++ ASSERT(p < endp); ++ ++ return (int)(p - buf); ++} ++#endif /* WLTINYDUMP || BCMDBG || WLMSG_INFORM || WLMSG_ASSOC || WLMSG_PRPKT */ ++ ++#endif /* BCMDRIVER */ ++ ++/* ++ * ProcessVars:Takes a buffer of "=\n" lines read from a file and ending in a NUL. ++ * also accepts nvram files which are already in the format of =\0\=\0 ++ * Removes carriage returns, empty lines, comment lines, and converts newlines to NULs. ++ * Shortens buffer as needed and pads with NULs. End of buffer is marked by two NULs. ++*/ ++ ++unsigned int ++process_nvram_vars(char *varbuf, unsigned int len) ++{ ++ char *dp; ++ bool findNewline; ++ int column; ++ unsigned int buf_len, n; ++ unsigned int pad = 0; ++ ++ dp = varbuf; ++ ++ findNewline = FALSE; ++ column = 0; ++ ++ for (n = 0; n < len; n++) { ++ if (varbuf[n] == '\r') { ++ continue; ++ } ++ if (findNewline && varbuf[n] != '\n') { ++ continue; ++ } ++ findNewline = FALSE; ++ if (varbuf[n] == '#') { ++ findNewline = TRUE; ++ continue; ++ } ++ if (varbuf[n] == '\n') { ++ if (column == 0) { ++ continue; ++ } ++ *dp++ = 0; ++ column = 0; ++ continue; ++ } ++ *dp++ = varbuf[n]; ++ column++; ++ } ++ buf_len = (unsigned int)(dp - varbuf); ++ if (buf_len % 4) { ++ pad = 4 - buf_len % 4; ++ if (pad && (buf_len + pad <= len)) { ++ buf_len += pad; ++ } ++ } ++ ++ while (dp < varbuf + n) { ++ *dp++ = 0; ++ } ++ ++ return buf_len; ++} +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/gh2_erom.c b/drivers/net/ethernet/broadcom/gmac/src/shared/gh2_erom.c +--- a/drivers/net/ethernet/broadcom/gmac/src/shared/gh2_erom.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/shared/gh2_erom.c 2017-11-09 17:53:44.032304000 +0800 +@@ -0,0 +1,18 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ * ++ * Broadcom Home Networking Division 10/100 Mbit/s Ethernet ++ * Greyhound2 sudo EROM ++ * ++ */ ++#include ++ ++uint32 gh2_erom[] = { ++ //#define CC_CORE_ID 0x800 /* chipcommon core */ ++ 0x4bf80001, 0x2a004201, 0x18000005, 0x181200c5, ++ //#define GMAC_CORE_ID 0x82d /* Gigabit MAC core */ ++ 0x4bf82d01, 0x04004211, 0x00000103, 0x18042005, 0x181100c5, ++ 0x4bf82d01, 0x04004211, 0x00000203, 0x1804a005, 0x181110c5, ++ 0x0000000f ++}; ++ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/gh2_erom.h b/drivers/net/ethernet/broadcom/gmac/src/shared/gh2_erom.h +--- a/drivers/net/ethernet/broadcom/gmac/src/shared/gh2_erom.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/shared/gh2_erom.h 2017-11-09 17:53:44.033296000 +0800 +@@ -0,0 +1,14 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ * ++ * Broadcom Home Networking Division 10/100 Mbit/s Ethernet ++ * Greyhound2 sudo EROM ++ * ++ */ ++ ++#ifndef _gh2_erom_h_ ++#define _gh2_erom_h_ ++ ++extern uint32 gh2_erom[]; ++ ++#endif /* _gh2_erom_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/gh_erom.c b/drivers/net/ethernet/broadcom/gmac/src/shared/gh_erom.c +--- a/drivers/net/ethernet/broadcom/gmac/src/shared/gh_erom.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/shared/gh_erom.c 2017-11-09 17:53:44.034292000 +0800 +@@ -0,0 +1,28 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Broadcom Home Networking Division 10/100 Mbit/s Ethernet ++ * Greyhound sudo EROM ++ * ++ */ ++#include ++ ++uint32 gh_erom[] = { ++ //#define CC_CORE_ID 0x800 /* chipcommon core */ ++ 0x4bf80001, 0x2a004201, 0x18000005, 0x181200c5, ++ //#define GMAC_CORE_ID 0x82d /* Gigabit MAC core */ ++ 0x4bf82d01, 0x04004211, 0x00000103, 0x18042005, 0x181100c5, ++ 0x0000000f ++}; +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/gh_erom.h b/drivers/net/ethernet/broadcom/gmac/src/shared/gh_erom.h +--- a/drivers/net/ethernet/broadcom/gmac/src/shared/gh_erom.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/shared/gh_erom.h 2017-11-09 17:53:44.035289000 +0800 +@@ -0,0 +1,26 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Broadcom Home Networking Division 10/100 Mbit/s Ethernet ++ * Greyhound sudo EROM ++ * ++ */ ++ ++#ifndef _gh_erom_h_ ++#define _gh_erom_h_ ++ ++extern uint32 gh_erom[]; ++ ++#endif /* _gh_erom_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/hnddma.c b/drivers/net/ethernet/broadcom/gmac/src/shared/hnddma.c +--- a/drivers/net/ethernet/broadcom/gmac/src/shared/hnddma.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/shared/hnddma.c 2017-11-09 17:53:44.045302000 +0800 +@@ -0,0 +1,3701 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Generic Broadcom Home Networking Division (HND) DMA module. ++ * This supports the following chips: BCM42xx, 44xx, 47xx . ++ * ++ * $Id: hnddma.c 328477 2012-04-19 10:57:54Z $ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#ifdef CONFIG_BCM_IPROC_GMAC_PREFETCH ++#include ++#endif ++ ++#ifdef CONFIG_BCM_IPROC_GMAC_RWREG_OPT ++#ifdef R_REG ++#undef R_REG ++#define R_REG(osh, r) (\ ++ sizeof(*(r)) == sizeof(uint8) ? (*(volatile unsigned char __force *)(r)) : \ ++ sizeof(*(r)) == sizeof(uint16) ? (*(volatile unsigned short __force *)(r)) : \ ++ (*(volatile unsigned int __force *)(r)) \ ++) ++#endif /* R_REG */ ++ ++#ifdef W_REG ++#undef W_REG ++#define W_REG(osh, r, v) (\ ++ sizeof(*(r)) == sizeof(uint8) ? (*(volatile unsigned char __force *)(r) = (v)) : \ ++ sizeof(*(r)) == sizeof(uint16) ? (*(volatile unsigned short __force *)(r) = (v)) : \ ++ (*(volatile unsigned int __force *)(r) = (v)) \ ++) ++#endif /* W_REG */ ++#endif /* CONFIG_BCM_IPROC_GMAC_RWREG_OPT */ ++ ++/* debug/trace */ ++#ifdef BCMDBG ++#define DMA_ERROR(args) if (!(*di->msg_level & 1)); else printf args ++#define DMA_TRACE(args) if (!(*di->msg_level & 2)); else printf args ++#elif defined(BCMDBG_ERR) ++#define DMA_ERROR(args) if (!(*di->msg_level & 1)); else printf args ++#define DMA_TRACE(args) ++#else ++#define DMA_ERROR(args) ++#define DMA_TRACE(args) ++#endif /* BCMDBG */ ++ ++#define DMA_NONE(args) ++ ++ ++#define d32txregs dregs.d32_u.txregs_32 ++#define d32rxregs dregs.d32_u.rxregs_32 ++#define txd32 dregs.d32_u.txd_32 ++#define rxd32 dregs.d32_u.rxd_32 ++ ++#define d64txregs dregs.d64_u.txregs_64 ++#define d64rxregs dregs.d64_u.rxregs_64 ++#define txd64 dregs.d64_u.txd_64 ++#define rxd64 dregs.d64_u.rxd_64 ++ ++#define DBG(x...) printk(KERN_ERR x) ++ ++/* default dma message level (if input msg_level pointer is null in dma_attach()) */ ++#ifdef BCMDBG_ERR ++static uint dma_msg_level = 1; ++#else ++static uint dma_msg_level = 0; ++#endif /* BCMDBG_ERR */ ++ ++#define MAXNAMEL 8 /* 8 char names */ ++ ++#define DI_INFO(dmah) ((dma_info_t *)dmah) ++ ++/* dma engine software state */ ++typedef struct dma_info { ++ struct hnddma_pub hnddma; /* exported structure, don't use hnddma_t, ++ * which could be const ++ */ ++ uint *msg_level; /* message level pointer */ ++ char name[MAXNAMEL]; /* callers name for diag msgs */ ++ ++ void *osh; /* os handle */ ++ si_t *sih; /* sb handle */ ++ ++ bool dma64; /* this dma engine is operating in 64-bit mode */ ++ bool addrext; /* this dma engine supports DmaExtendedAddrChanges */ ++ ++ union { ++ struct { ++ dma32regs_t *txregs_32; /* 32-bit dma tx engine registers */ ++ dma32regs_t *rxregs_32; /* 32-bit dma rx engine registers */ ++ dma32dd_t *txd_32; /* pointer to dma32 tx descriptor ring */ ++ dma32dd_t *rxd_32; /* pointer to dma32 rx descriptor ring */ ++ } d32_u; ++ struct { ++ dma64regs_t *txregs_64; /* 64-bit dma tx engine registers */ ++ dma64regs_t *rxregs_64; /* 64-bit dma rx engine registers */ ++ dma64dd_t *txd_64; /* pointer to dma64 tx descriptor ring */ ++ dma64dd_t *rxd_64; /* pointer to dma64 rx descriptor ring */ ++ } d64_u; ++ } dregs; ++ ++ uint16 dmadesc_align; /* alignment requirement for dma descriptors */ ++ ++ uint16 ntxd; /* # tx descriptors tunable */ ++ uint16 txin; /* index of next descriptor to reclaim */ ++ uint16 txout; /* index of next descriptor to post */ ++ void **txp; /* pointer to parallel array of pointers to packets */ ++ osldma_t *tx_dmah; /* DMA TX descriptor ring handle */ ++ hnddma_seg_map_t *txp_dmah; /* DMA MAP meta-data handle */ ++ dmaaddr_t txdpa; /* Aligned physical address of descriptor ring */ ++ dmaaddr_t txdpaorig; /* Original physical address of descriptor ring */ ++ uint16 txdalign; /* #bytes added to alloc'd mem to align txd */ ++ uint32 txdalloc; /* #bytes allocated for the ring */ ++ uint32 xmtptrbase; /* When using unaligned descriptors, the ptr register ++ * is not just an index, it needs all 13 bits to be ++ * an offset from the addr register. ++ */ ++ ++ uint16 nrxd; /* # rx descriptors tunable */ ++ uint16 rxin; /* index of next descriptor to reclaim */ ++ uint16 rxout; /* index of next descriptor to post */ ++ void **rxp; /* pointer to parallel array of pointers to packets */ ++ osldma_t *rx_dmah; /* DMA RX descriptor ring handle */ ++ hnddma_seg_map_t *rxp_dmah; /* DMA MAP meta-data handle */ ++ dmaaddr_t rxdpa; /* Aligned physical address of descriptor ring */ ++ dmaaddr_t rxdpaorig; /* Original physical address of descriptor ring */ ++ uint16 rxdalign; /* #bytes added to alloc'd mem to align rxd */ ++ uint32 rxdalloc; /* #bytes allocated for the ring */ ++ uint32 rcvptrbase; /* Base for ptr reg when using unaligned descriptors */ ++ ++ /* tunables */ ++ uint16 rxbufsize; /* rx buffer size in bytes, ++ * not including the extra headroom ++ */ ++ uint rxextrahdrroom; /* extra rx headroom, reverseved to assist upper stack ++ * e.g. some rx pkt buffers will be bridged to tx side ++ * without byte copying. The extra headroom needs to be ++ * large enough to fit txheader needs. ++ * Some dongle driver may not need it. ++ */ ++ uint nrxpost; /* # rx buffers to keep posted */ ++ uint rxoffset; /* rxcontrol offset */ ++ uint ddoffsetlow; /* add to get dma address of descriptor ring, low 32 bits */ ++ uint ddoffsethigh; /* high 32 bits */ ++ uint dataoffsetlow; /* add to get dma address of data buffer, low 32 bits */ ++ uint dataoffsethigh; /* high 32 bits */ ++ bool aligndesc_4k; /* descriptor base need to be aligned or not */ ++ uint8 rxburstlen; /* burstlen field for rx (for cores supporting burstlen) */ ++ uint8 txburstlen; /* burstlen field for tx (for cores supporting burstlen) */ ++ uint8 txmultioutstdrd; /* tx multiple outstanding reads */ ++ uint8 txprefetchctl; /* prefetch control for tx */ ++ uint8 txprefetchthresh; /* prefetch threshold for tx */ ++ uint8 rxprefetchctl; /* prefetch control for rx */ ++ uint8 rxprefetchthresh; /* prefetch threshold for rx */ ++ pktpool_t *pktpool; /* pktpool */ ++ uint dma_avoidance_cnt; ++ ++ uint32 d64_xs0_cd_mask; /* tx current descriptor pointer mask */ ++ uint32 d64_xs1_ad_mask; /* tx active descriptor mask */ ++ uint32 d64_rs0_cd_mask; /* rx current descriptor pointer mask */ ++ uint16 rs0cd; /* cached value of rcvstatus0 currdescr */ ++ uint16 xs0cd; /* cached value of xmtstatus0 currdescr */ ++ uint16 xs0cd_snapshot; /* snapshot of xmtstatus0 currdescr */ ++ spinlock_t des_lock; ++} dma_info_t; ++ ++/* ++ * If BCMDMA32 is defined, hnddma will support both 32-bit and 64-bit DMA engines. ++ * Otherwise it will support only 64-bit. ++ * ++ * DMA32_ENAB indicates whether hnddma is compiled with support for 32-bit DMA engines. ++ * DMA64_ENAB indicates whether hnddma is compiled with support for 64-bit DMA engines. ++ * ++ * DMA64_MODE indicates whether the current DMA engine is running as 64-bit. ++ */ ++#ifdef BCMDMA32 ++#define DMA32_ENAB(di) 1 ++#define DMA64_ENAB(di) 1 ++#define DMA64_MODE(di) ((di)->dma64) ++#else /* !BCMDMA32 */ ++#define DMA32_ENAB(di) 0 ++#define DMA64_ENAB(di) 1 ++#define DMA64_MODE(di) 1 ++#endif /* !BCMDMA32 */ ++ ++/* DMA Scatter-gather list is supported. Note this is limited to TX direction only */ ++#ifdef BCMDMASGLISTOSL ++#define DMASGLIST_ENAB TRUE ++#else ++#define DMASGLIST_ENAB FALSE ++#endif /* BCMDMASGLISTOSL */ ++ ++/* descriptor bumping macros */ ++#define XXD(x, n) ((x) & ((n) - 1)) /* faster than %, but n must be power of 2 */ ++#define TXD(x) XXD((x), di->ntxd) ++#define RXD(x) XXD((x), di->nrxd) ++#define NEXTTXD(i) TXD((i) + 1) ++#define PREVTXD(i) TXD((i) - 1) ++#define NEXTRXD(i) RXD((i) + 1) ++#define PREVRXD(i) RXD((i) - 1) ++ ++#define NTXDACTIVE(h, t) TXD((t) - (h)) ++#define NRXDACTIVE(h, t) RXD((t) - (h)) ++ ++/* macros to convert between byte offsets and indexes */ ++#define B2I(bytes, type) ((uint16)((bytes) / sizeof(type))) ++#define I2B(index, type) ((index) * sizeof(type)) ++ ++#define PCI32ADDR_HIGH 0xc0000000 /* address[31:30] */ ++#define PCI32ADDR_HIGH_SHIFT 30 /* address[31:30] */ ++ ++#define PCI64ADDR_HIGH 0x80000000 /* address[63] */ ++#define PCI64ADDR_HIGH_SHIFT 31 /* address[63] */ ++ ++ ++#ifdef CONFIG_BCM_IPROC_GMAC_PREFETCH ++#define SKB_PREFETCH_LEN (128) ++#endif ++ ++/* Common prototypes */ ++static bool _dma_isaddrext(dma_info_t *di); ++static bool _dma_descriptor_align(dma_info_t *di); ++static bool _dma_alloc(dma_info_t *di, uint direction); ++static void _dma_detach(dma_info_t *di); ++static void _dma_ddtable_init(dma_info_t *di, uint direction, dmaaddr_t pa); ++static void _dma_rxinit(dma_info_t *di); ++static void *_dma_rx(dma_info_t *di); ++static bool _dma_rxfill(dma_info_t *di); ++static void _dma_rxreclaim(dma_info_t *di); ++static void _dma_rxenable(dma_info_t *di); ++static void *_dma_getnextrxp(dma_info_t *di, bool forceall); ++static void _dma_rx_param_get(dma_info_t *di, uint16 *rxoffset, uint16 *rxbufsize); ++ ++static void _dma_txblock(dma_info_t *di); ++static void _dma_txunblock(dma_info_t *di); ++static uint _dma_txactive(dma_info_t *di); ++static uint _dma_rxactive(dma_info_t *di); ++static uint _dma_activerxbuf(dma_info_t *di); ++static uint _dma_txpending(dma_info_t *di); ++static uint _dma_txcommitted(dma_info_t *di); ++ ++static void *_dma_peeknexttxp(dma_info_t *di); ++static int _dma_peekntxp(dma_info_t *di, int *len, void *txps[], txd_range_t range); ++static void *_dma_peeknextrxp(dma_info_t *di); ++static uintptr _dma_getvar(dma_info_t *di, const char *name); ++static void _dma_counterreset(dma_info_t *di); ++static void _dma_fifoloopbackenable(dma_info_t *di); ++static uint _dma_ctrlflags(dma_info_t *di, uint mask, uint flags); ++static uint8 dma_align_sizetobits(uint size); ++static void *dma_ringalloc(osl_t *osh, uint32 boundary, uint size, uint16 *alignbits, uint* alloced, ++ dmaaddr_t *descpa, osldma_t **dmah); ++static int _dma_pktpool_set(dma_info_t *di, pktpool_t *pool); ++static bool _dma_rxtx_error(dma_info_t *di, bool istx); ++static void _dma_burstlen_set(dma_info_t *di, uint8 rxburstlen, uint8 txburstlen); ++static uint _dma_avoidancecnt(dma_info_t *di); ++static void _dma_param_set(dma_info_t *di, uint16 paramid, uint16 paramval); ++static bool _dma_glom_enable(dma_info_t *di, uint32 val); ++ ++ ++/* Prototypes for 32-bit routines */ ++static bool dma32_alloc(dma_info_t *di, uint direction); ++static bool dma32_txreset(dma_info_t *di); ++static bool dma32_rxreset(dma_info_t *di); ++static bool dma32_txsuspendedidle(dma_info_t *di); ++static int dma32_txfast(dma_info_t *di, void *p0, bool commit); ++static void *dma32_getnexttxp(dma_info_t *di, txd_range_t range); ++static void *dma32_getnextrxp(dma_info_t *di, bool forceall); ++static void dma32_txrotate(dma_info_t *di); ++static bool dma32_rxidle(dma_info_t *di); ++static void dma32_txinit(dma_info_t *di); ++static bool dma32_txenabled(dma_info_t *di); ++static void dma32_txsuspend(dma_info_t *di); ++static void dma32_txresume(dma_info_t *di); ++static bool dma32_txsuspended(dma_info_t *di); ++#ifdef WL_MULTIQUEUE ++static void dma32_txflush(dma_info_t *di); ++static void dma32_txflush_clear(dma_info_t *di); ++#endif /* WL_MULTIQUEUE */ ++static void dma32_txreclaim(dma_info_t *di, txd_range_t range); ++static bool dma32_txstopped(dma_info_t *di); ++static bool dma32_rxstopped(dma_info_t *di); ++static bool dma32_rxenabled(dma_info_t *di); ++#if defined(BCMDBG) ++static void dma32_dumpring(dma_info_t *di, struct bcmstrbuf *b, dma32dd_t *ring, uint start, ++ uint end, uint max_num); ++static void dma32_dump(dma_info_t *di, struct bcmstrbuf *b, bool dumpring); ++static void dma32_dumptx(dma_info_t *di, struct bcmstrbuf *b, bool dumpring); ++static void dma32_dumprx(dma_info_t *di, struct bcmstrbuf *b, bool dumpring); ++#endif ++ ++static bool _dma32_addrext(osl_t *osh, dma32regs_t *dma32regs); ++ ++/* Prototypes for 64-bit routines */ ++static bool dma64_alloc(dma_info_t *di, uint direction); ++static bool dma64_txreset(dma_info_t *di); ++static bool dma64_rxreset(dma_info_t *di); ++static bool dma64_txsuspendedidle(dma_info_t *di); ++static int dma64_txfast(dma_info_t *di, void *p0, bool commit); ++static int dma64_txunframed(dma_info_t *di, void *p0, uint len, bool commit); ++static void *dma64_getpos(dma_info_t *di, bool direction); ++static void *dma64_getnexttxp(dma_info_t *di, txd_range_t range); ++static void *dma64_getnextrxp(dma_info_t *di, bool forceall); ++static void dma64_txrotate(dma_info_t *di); ++ ++static bool dma64_rxidle(dma_info_t *di); ++static void dma64_txinit(dma_info_t *di); ++static bool dma64_txenabled(dma_info_t *di); ++static void dma64_txsuspend(dma_info_t *di); ++static void dma64_txresume(dma_info_t *di); ++static bool dma64_txsuspended(dma_info_t *di); ++#ifdef WL_MULTIQUEUE ++static void dma64_txflush(dma_info_t *di); ++static void dma64_txflush_clear(dma_info_t *di); ++#endif /* WL_MULTIQUEUE */ ++static void dma64_txreclaim(dma_info_t *di, txd_range_t range); ++static bool dma64_txstopped(dma_info_t *di); ++static bool dma64_rxstopped(dma_info_t *di); ++static bool dma64_rxenabled(dma_info_t *di); ++static bool _dma64_addrext(osl_t *osh, dma64regs_t *dma64regs); ++static int dma64_rxunframed(dma_info_t *di, void *p0, uint len, bool commit); ++ ++STATIC INLINE uint32 parity32(uint32 data); ++ ++#if defined(BCMDBG) ++static void dma64_dumpring(dma_info_t *di, struct bcmstrbuf *b, dma64dd_t *ring, uint start, ++ uint end, uint max_num); ++static void dma64_dump(dma_info_t *di, struct bcmstrbuf *b, bool dumpring); ++static void dma64_dumptx(dma_info_t *di, struct bcmstrbuf *b, bool dumpring); ++static void dma64_dumprx(dma_info_t *di, struct bcmstrbuf *b, bool dumpring); ++#endif ++ ++ ++const di_fcn_t dma64proc = { ++ (di_detach_t)_dma_detach, ++ (di_txinit_t)dma64_txinit, ++ (di_txreset_t)dma64_txreset, ++ (di_txenabled_t)dma64_txenabled, ++ (di_txsuspend_t)dma64_txsuspend, ++ (di_txresume_t)dma64_txresume, ++ (di_txsuspended_t)dma64_txsuspended, ++ (di_txsuspendedidle_t)dma64_txsuspendedidle, ++#ifdef WL_MULTIQUEUE ++ (di_txflush_t)dma64_txflush, ++ (di_txflush_clear_t)dma64_txflush_clear, ++#endif /* WL_MULTIQUEUE */ ++ (di_txfast_t)dma64_txfast, ++ (di_txunframed_t)dma64_txunframed, ++ (di_getpos_t)dma64_getpos, ++ (di_txstopped_t)dma64_txstopped, ++ (di_txreclaim_t)dma64_txreclaim, ++ (di_getnexttxp_t)dma64_getnexttxp, ++ (di_peeknexttxp_t)_dma_peeknexttxp, ++ (di_peekntxp_t)_dma_peekntxp, ++ (di_txblock_t)_dma_txblock, ++ (di_txunblock_t)_dma_txunblock, ++ (di_txactive_t)_dma_txactive, ++ (di_txrotate_t)dma64_txrotate, ++ ++ (di_rxinit_t)_dma_rxinit, ++ (di_rxreset_t)dma64_rxreset, ++ (di_rxidle_t)dma64_rxidle, ++ (di_rxstopped_t)dma64_rxstopped, ++ (di_rxenable_t)_dma_rxenable, ++ (di_rxenabled_t)dma64_rxenabled, ++ (di_rx_t)_dma_rx, ++ (di_rxfill_t)_dma_rxfill, ++ (di_rxreclaim_t)_dma_rxreclaim, ++ (di_getnextrxp_t)_dma_getnextrxp, ++ (di_peeknextrxp_t)_dma_peeknextrxp, ++ (di_rxparam_get_t)_dma_rx_param_get, ++ ++ (di_fifoloopbackenable_t)_dma_fifoloopbackenable, ++ (di_getvar_t)_dma_getvar, ++ (di_counterreset_t)_dma_counterreset, ++ (di_ctrlflags_t)_dma_ctrlflags, ++ ++#if defined(BCMDBG) ++ (di_dump_t)dma64_dump, ++ (di_dumptx_t)dma64_dumptx, ++ (di_dumprx_t)dma64_dumprx, ++#else ++ NULL, ++ NULL, ++ NULL, ++#endif ++ (di_rxactive_t)_dma_rxactive, ++ (di_txpending_t)_dma_txpending, ++ (di_txcommitted_t)_dma_txcommitted, ++ (di_pktpool_set_t)_dma_pktpool_set, ++ (di_rxtxerror_t)_dma_rxtx_error, ++ (di_burstlen_set_t)_dma_burstlen_set, ++ (di_avoidancecnt_t)_dma_avoidancecnt, ++ (di_param_set_t)_dma_param_set, ++ (dma_glom_enable_t)_dma_glom_enable, ++ (di_rxunframed_t)dma64_rxunframed, ++ (dma_active_rxbuf_t)_dma_activerxbuf, ++ 40 ++}; ++ ++static const di_fcn_t dma32proc = { ++ (di_detach_t)_dma_detach, ++ (di_txinit_t)dma32_txinit, ++ (di_txreset_t)dma32_txreset, ++ (di_txenabled_t)dma32_txenabled, ++ (di_txsuspend_t)dma32_txsuspend, ++ (di_txresume_t)dma32_txresume, ++ (di_txsuspended_t)dma32_txsuspended, ++ (di_txsuspendedidle_t)dma32_txsuspendedidle, ++#ifdef WL_MULTIQUEUE ++ (di_txflush_t)dma32_txflush, ++ (di_txflush_clear_t)dma32_txflush_clear, ++#endif /* WL_MULTIQUEUE */ ++ (di_txfast_t)dma32_txfast, ++ NULL, ++ NULL, ++ (di_txstopped_t)dma32_txstopped, ++ (di_txreclaim_t)dma32_txreclaim, ++ (di_getnexttxp_t)dma32_getnexttxp, ++ (di_peeknexttxp_t)_dma_peeknexttxp, ++ (di_peekntxp_t)_dma_peekntxp, ++ (di_txblock_t)_dma_txblock, ++ (di_txunblock_t)_dma_txunblock, ++ (di_txactive_t)_dma_txactive, ++ (di_txrotate_t)dma32_txrotate, ++ ++ (di_rxinit_t)_dma_rxinit, ++ (di_rxreset_t)dma32_rxreset, ++ (di_rxidle_t)dma32_rxidle, ++ (di_rxstopped_t)dma32_rxstopped, ++ (di_rxenable_t)_dma_rxenable, ++ (di_rxenabled_t)dma32_rxenabled, ++ (di_rx_t)_dma_rx, ++ (di_rxfill_t)_dma_rxfill, ++ (di_rxreclaim_t)_dma_rxreclaim, ++ (di_getnextrxp_t)_dma_getnextrxp, ++ (di_peeknextrxp_t)_dma_peeknextrxp, ++ (di_rxparam_get_t)_dma_rx_param_get, ++ ++ (di_fifoloopbackenable_t)_dma_fifoloopbackenable, ++ (di_getvar_t)_dma_getvar, ++ (di_counterreset_t)_dma_counterreset, ++ (di_ctrlflags_t)_dma_ctrlflags, ++ ++#if defined(BCMDBG) ++ (di_dump_t)dma32_dump, ++ (di_dumptx_t)dma32_dumptx, ++ (di_dumprx_t)dma32_dumprx, ++#else ++ NULL, ++ NULL, ++ NULL, ++#endif ++ (di_rxactive_t)_dma_rxactive, ++ (di_txpending_t)_dma_txpending, ++ (di_txcommitted_t)_dma_txcommitted, ++ (di_pktpool_set_t)_dma_pktpool_set, ++ (di_rxtxerror_t)_dma_rxtx_error, ++ (di_burstlen_set_t)_dma_burstlen_set, ++ (di_avoidancecnt_t)_dma_avoidancecnt, ++ (di_param_set_t)_dma_param_set, ++ NULL, ++ NULL, ++ NULL, ++ 40 ++}; ++ ++EXPORT_SYMBOL(dma_attach); ++EXPORT_SYMBOL(dma64proc); ++ ++hnddma_t * ++dma_attach(osl_t *osh, const char *name, si_t *sih, ++ volatile void *dmaregstx, volatile void *dmaregsrx, ++ uint ntxd, uint nrxd, uint rxbufsize, int rxextheadroom, uint nrxpost, uint rxoffset, ++ uint *msg_level) ++{ ++ dma_info_t *di; ++ uint size; ++ uint32 mask; ++ ++ /* allocate private info structure */ ++ if ((di = MALLOC(osh, sizeof (dma_info_t))) == NULL) { ++#ifdef BCMDBG ++ DMA_ERROR(("%s: out of memory, malloced %d bytes\n", __FUNCTION__, MALLOCED(osh))); ++#endif ++ return (NULL); ++ } ++ ++ bzero(di, sizeof(dma_info_t)); ++ ++ di->msg_level = msg_level ? msg_level : &dma_msg_level; ++ spin_lock_init(&di->des_lock); ++ ++ /* old chips w/o sb is no longer supported */ ++ ASSERT(sih != NULL); ++ ++ if (DMA64_ENAB(di)) { ++ di->dma64 = ((si_core_sflags(sih, 0, 0) & SISF_DMA64) == SISF_DMA64); ++ } else { ++ di->dma64 = 0; ++ } ++ ++ /* check arguments */ ++ ASSERT(ISPOWEROF2(ntxd)); ++ ASSERT(ISPOWEROF2(nrxd)); ++ ++ if (nrxd == 0) { ++ ASSERT(dmaregsrx == NULL); ++ } ++ if (ntxd == 0) { ++ ASSERT(dmaregstx == NULL); ++ } ++ ++ /* init dma reg pointer */ ++ if (DMA64_ENAB(di) && DMA64_MODE(di)) { ++ di->d64txregs = (dma64regs_t *)dmaregstx; ++ di->d64rxregs = (dma64regs_t *)dmaregsrx; ++ di->hnddma.di_fn = (const di_fcn_t *)&dma64proc; ++ } else if (DMA32_ENAB(di)) { ++ ASSERT(ntxd <= D32MAXDD); ++ ASSERT(nrxd <= D32MAXDD); ++ di->d32txregs = (dma32regs_t *)dmaregstx; ++ di->d32rxregs = (dma32regs_t *)dmaregsrx; ++ di->hnddma.di_fn = (const di_fcn_t *)&dma32proc; ++ } else { ++ DMA_ERROR(("%s: driver doesn't support 32-bit DMA\n", __FUNCTION__)); ++ ASSERT(0); ++ goto fail; ++ } ++ ++ /* Default flags (which can be changed by the driver calling dma_ctrlflags ++ * before enable): For backwards compatibility both Rx Overflow Continue ++ * and Parity are DISABLED. ++ * supports it. ++ */ ++ di->hnddma.di_fn->ctrlflags(&di->hnddma, DMA_CTRL_ROC | DMA_CTRL_PEN, 0); ++ ++ DMA_TRACE(("%s: %s: %s osh %p flags 0x%x ntxd %d nrxd %d rxbufsize %d " ++ "rxextheadroom %d nrxpost %d rxoffset %d dmaregstx %p dmaregsrx %p\n", ++ name, __FUNCTION__, (DMA64_MODE(di) ? "DMA64" : "DMA32"), ++ osh, di->hnddma.dmactrlflags, ntxd, nrxd, ++ rxbufsize, rxextheadroom, nrxpost, rxoffset, dmaregstx, dmaregsrx)); ++ ++ /* make a private copy of our callers name */ ++ strncpy(di->name, name, MAXNAMEL); ++ di->name[MAXNAMEL-1] = '\0'; ++ ++ di->osh = osh; ++ di->sih = sih; ++ ++ /* save tunables */ ++ di->ntxd = (uint16)ntxd; ++ di->nrxd = (uint16)nrxd; ++ ++ /* the actual dma size doesn't include the extra headroom */ ++ di->rxextrahdrroom = (rxextheadroom == -1) ? BCMEXTRAHDROOM : rxextheadroom; ++ if (rxbufsize > BCMEXTRAHDROOM) { ++ di->rxbufsize = (uint16)(rxbufsize - di->rxextrahdrroom); ++ } else { ++ di->rxbufsize = (uint16)rxbufsize; ++ } ++ ++ di->nrxpost = (uint16)nrxpost; ++ di->rxoffset = (uint8)rxoffset; ++ ++ /* Get the default values (POR) of the burstlen. This can be overridden by the modules ++ * if this has to be different. Otherwise this value will be used to program the control ++ * register after the reset or during the init. ++ */ ++ if (dmaregsrx) { ++ if (DMA64_ENAB(di) && DMA64_MODE(di)) { ++ /* detect the dma descriptor address mask, ++ * should be 0x1fff before 4360B0, 0xffff start from 4360B0 ++ */ ++ W_REG(di->osh, &di->d64rxregs->addrlow, 0xffffffff); ++ mask = R_REG(di->osh, &di->d64rxregs->addrlow); ++ ++ if (mask & 0xfff) { ++ mask = R_REG(di->osh, &di->d64rxregs->ptr) | 0xf; ++ } else { ++ mask = 0x1fff; ++ } ++ ++ DMA_TRACE(("%s: dma_rx_mask: %08x\n", di->name, mask)); ++ di->d64_rs0_cd_mask = mask; ++ ++ if (mask == 0x1fff) { ++ ASSERT(nrxd <= D64MAXDD); ++ } else { ++ ASSERT(nrxd <= D64MAXDD_LARGE); ++ } ++ ++ di->rxburstlen = (R_REG(di->osh, ++ &di->d64rxregs->control) & D64_RC_BL_MASK) >> D64_RC_BL_SHIFT; ++ di->rxprefetchctl = (R_REG(di->osh, ++ &di->d64rxregs->control) & D64_RC_PC_MASK) >> D64_RC_PC_SHIFT; ++ di->rxprefetchthresh = (R_REG(di->osh, ++ &di->d64rxregs->control) & D64_RC_PT_MASK) >> D64_RC_PT_SHIFT; ++ } else if (DMA32_ENAB(di)) { ++ di->rxburstlen = (R_REG(di->osh, ++ &di->d32rxregs->control) & RC_BL_MASK) >> RC_BL_SHIFT; ++ di->rxprefetchctl = (R_REG(di->osh, ++ &di->d32rxregs->control) & RC_PC_MASK) >> RC_PC_SHIFT; ++ di->rxprefetchthresh = (R_REG(di->osh, ++ &di->d32rxregs->control) & RC_PT_MASK) >> RC_PT_SHIFT; ++ } ++ } ++ if (dmaregstx) { ++ if (DMA64_ENAB(di) && DMA64_MODE(di)) { ++ ++ /* detect the dma descriptor address mask, ++ * should be 0x1fff before 4360B0, 0xffff start from 4360B0 ++ */ ++ W_REG(di->osh, &di->d64txregs->addrlow, 0xffffffff); ++ mask = R_REG(di->osh, &di->d64txregs->addrlow); ++ ++ if (mask & 0xfff) { ++ mask = R_REG(di->osh, &di->d64txregs->ptr) | 0xf; ++ } else { ++ mask = 0x1fff; ++ } ++ ++ DMA_TRACE(("%s: dma_tx_mask: %08x\n", di->name, mask)); ++ di->d64_xs0_cd_mask = mask; ++ di->d64_xs1_ad_mask = mask; ++ ++ if (mask == 0x1fff) { ++ ASSERT(ntxd <= D64MAXDD); ++ } else { ++ ASSERT(ntxd <= D64MAXDD_LARGE); ++ } ++ ++ di->txburstlen = (R_REG(di->osh, ++ &di->d64txregs->control) & D64_XC_BL_MASK) >> D64_XC_BL_SHIFT; ++ di->txmultioutstdrd = (R_REG(di->osh, ++ &di->d64txregs->control) & D64_XC_MR_MASK) >> D64_XC_MR_SHIFT; ++ di->txprefetchctl = (R_REG(di->osh, ++ &di->d64txregs->control) & D64_XC_PC_MASK) >> D64_XC_PC_SHIFT; ++ di->txprefetchthresh = (R_REG(di->osh, ++ &di->d64txregs->control) & D64_XC_PT_MASK) >> D64_XC_PT_SHIFT; ++ } else if (DMA32_ENAB(di)) { ++ di->txburstlen = (R_REG(di->osh, ++ &di->d32txregs->control) & XC_BL_MASK) >> XC_BL_SHIFT; ++ di->txmultioutstdrd = (R_REG(di->osh, ++ &di->d32txregs->control) & XC_MR_MASK) >> XC_MR_SHIFT; ++ di->txprefetchctl = (R_REG(di->osh, ++ &di->d32txregs->control) & XC_PC_MASK) >> XC_PC_SHIFT; ++ di->txprefetchthresh = (R_REG(di->osh, ++ &di->d32txregs->control) & XC_PT_MASK) >> XC_PT_SHIFT; ++ } ++ } ++ ++ /* force burstlen to 3 */ ++ di->rxburstlen = 3; ++ di->txburstlen = 3; ++ /* ++ * figure out the DMA physical address offset for dd and data ++ * Other bus: use zero ++ */ ++ di->ddoffsetlow = 0; ++ di->dataoffsetlow = 0; ++ ++ /* set addr ext fields */ ++ di->addrext = _dma_isaddrext(di); ++ ++ /* does the descriptors need to be aligned and if yes, on 4K/8K or not */ ++ di->aligndesc_4k = _dma_descriptor_align(di); ++ if (di->aligndesc_4k) { ++ if (DMA64_MODE(di)) { ++ di->dmadesc_align = D64RINGALIGN_BITS; ++ if ((ntxd < D64MAXDD / 2) && (nrxd < D64MAXDD / 2)) { ++ /* for smaller dd table, HW relax the alignment requirement */ ++ di->dmadesc_align = D64RINGALIGN_BITS - 1; ++ } ++ } else { ++ di->dmadesc_align = D32RINGALIGN_BITS; ++ } ++ } else { ++ /* The start address of descriptor table should be algined to cache line size, ++ * or other structure may share a cache line with it, which can lead to memory ++ * overlapping due to cache write-back operation. In the case of MIPS 74k, the ++ * cache line size is 32 bytes. ++ */ ++#ifdef __mips__ ++ di->dmadesc_align = 5; /* 32 byte alignment */ ++#else ++ di->dmadesc_align = 4; /* 16 byte alignment */ ++#endif ++ } ++ ++ DMA_NONE(("DMA descriptor align_needed %d, align %d\n", ++ di->aligndesc_4k, di->dmadesc_align)); ++ ++ /* allocate tx packet pointer vector */ ++ if (ntxd) { ++ size = ntxd * sizeof(void *); ++ if ((di->txp = MALLOC(osh, size)) == NULL) { ++ DMA_ERROR(("%s: %s: out of tx memory, malloced %d bytes\n", ++ di->name, __FUNCTION__, MALLOCED(osh))); ++ goto fail; ++ } ++ bzero(di->txp, size); ++ } ++ ++ /* allocate rx packet pointer vector */ ++ if (nrxd) { ++ size = nrxd * sizeof(void *); ++ if ((di->rxp = MALLOC(osh, size)) == NULL) { ++ DMA_ERROR(("%s: %s: out of rx memory, malloced %d bytes\n", ++ di->name, __FUNCTION__, MALLOCED(osh))); ++ goto fail; ++ } ++ bzero(di->rxp, size); ++ } ++ ++ /* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */ ++ if (ntxd) { ++ if (!_dma_alloc(di, DMA_TX)) { ++ goto fail; ++ } ++ } ++ ++ /* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */ ++ if (nrxd) { ++ if (!_dma_alloc(di, DMA_RX)) { ++ goto fail; ++ } ++ } ++ ++ if ((di->ddoffsetlow != 0) && !di->addrext) { ++ if (PHYSADDRLO(di->txdpa) > SI_PCI_DMA_SZ) { ++ DMA_ERROR(("%s: %s: txdpa 0x%x: addrext not supported\n", ++ di->name, __FUNCTION__, (uint32)PHYSADDRLO(di->txdpa))); ++ goto fail; ++ } ++ if (PHYSADDRLO(di->rxdpa) > SI_PCI_DMA_SZ) { ++ DMA_ERROR(("%s: %s: rxdpa 0x%x: addrext not supported\n", ++ di->name, __FUNCTION__, (uint32)PHYSADDRLO(di->rxdpa))); ++ goto fail; ++ } ++ } ++ ++ DMA_TRACE(("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh " ++ "0x%x addrext %d\n", di->ddoffsetlow, di->ddoffsethigh, di->dataoffsetlow, ++ di->dataoffsethigh, di->addrext)); ++ ++ /* allocate DMA mapping vectors */ ++ if (DMASGLIST_ENAB) { ++ if (ntxd) { ++ size = ntxd * sizeof(hnddma_seg_map_t); ++ if ((di->txp_dmah = (hnddma_seg_map_t *)MALLOC(osh, size)) == NULL) { ++ goto fail; ++ } ++ bzero(di->txp_dmah, size); ++ } ++ ++ if (nrxd) { ++ size = nrxd * sizeof(hnddma_seg_map_t); ++ if ((di->rxp_dmah = (hnddma_seg_map_t *)MALLOC(osh, size)) == NULL) { ++ goto fail; ++ } ++ bzero(di->rxp_dmah, size); ++ } ++ } ++ ++ return ((hnddma_t *)di); ++ ++fail: ++ _dma_detach(di); ++ return (NULL); ++} ++ ++/* init the tx or rx descriptor */ ++static INLINE void ++dma32_dd_upd(dma_info_t *di, dma32dd_t *ddring, dmaaddr_t pa, uint outidx, uint32 *flags, ++ uint32 bufcount) ++{ ++ /* dma32 uses 32-bit control to fit both flags and bufcounter */ ++ *flags = *flags | (bufcount & CTRL_BC_MASK); ++ ++ if ((di->dataoffsetlow == 0) || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) { ++ W_SM(&ddring[outidx].addr, BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow)); ++ W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*flags)); ++ } else { ++ /* address extension */ ++ uint32 ae; ++ ASSERT(di->addrext); ++ ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; ++ PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH; ++ ++ *flags |= (ae << CTRL_AE_SHIFT); ++ W_SM(&ddring[outidx].addr, BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow)); ++ W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*flags)); ++ } ++} ++ ++/* Check for odd number of 1's */ ++STATIC INLINE uint32 parity32(uint32 data) ++{ ++ data ^= data >> 16; ++ data ^= data >> 8; ++ data ^= data >> 4; ++ data ^= data >> 2; ++ data ^= data >> 1; ++ ++ return (data & 1); ++} ++ ++#define DMA64_DD_PARITY(dd) parity32((dd)->addrlow ^ (dd)->addrhigh ^ (dd)->ctrl1 ^ (dd)->ctrl2) ++ ++static INLINE void ++dma64_dd_upd(dma_info_t *di, dma64dd_t *ddring, dmaaddr_t pa, uint outidx, uint32 *flags, ++ uint32 bufcount) ++{ ++ uint32 ctrl2 = bufcount & D64_CTRL2_BC_MASK; ++ ++ /* PCI bus with big(>1G) physical address, use address extension */ ++#if defined(__mips__) && defined(IL_BIGENDIAN) ++ if ((di->dataoffsetlow == SI_SDRAM_SWAPPED) || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) { ++#else ++ if ((di->dataoffsetlow == 0) || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) { ++#endif /* defined(__mips__) && defined(IL_BIGENDIAN) */ ++ ASSERT((PHYSADDRHI(pa) & PCI64ADDR_HIGH) == 0); ++ ++ W_SM(&ddring[outidx].addrlow, BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow)); ++ W_SM(&ddring[outidx].addrhigh, BUS_SWAP32(PHYSADDRHI(pa) + di->dataoffsethigh)); ++ W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags)); ++ W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2)); ++ } else { ++ /* address extension for 32-bit PCI */ ++ uint32 ae; ++ ASSERT(di->addrext); ++ ++ ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; ++ PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH; ++ ASSERT(PHYSADDRHI(pa) == 0); ++ ++ ctrl2 |= (ae << D64_CTRL2_AE_SHIFT) & D64_CTRL2_AE; ++ W_SM(&ddring[outidx].addrlow, BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow)); ++ W_SM(&ddring[outidx].addrhigh, BUS_SWAP32(0 + di->dataoffsethigh)); ++ W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags)); ++ W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2)); ++ } ++ if (di->hnddma.dmactrlflags & DMA_CTRL_PEN) { ++ if (DMA64_DD_PARITY(&ddring[outidx])) { ++ W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2 | D64_CTRL2_PARITY)); ++ } ++ } ++ ++#ifndef CONFIG_BCM_IPROC_GMAC_ACP ++/* Test */ ++#if defined(__arm__) ++ OSL_CACHE_FLUSH((uint)OSL_CACHED(&ddring[outidx]), sizeof(dma64dd_t)); ++#endif ++#endif /* ! CONFIG_BCM_IPROC_GMAC_ACP */ ++} ++ ++static bool ++_dma32_addrext(osl_t *osh, dma32regs_t *dma32regs) ++{ ++ uint32 w; ++ ++ OR_REG(osh, &dma32regs->control, XC_AE); ++ w = R_REG(osh, &dma32regs->control); ++ AND_REG(osh, &dma32regs->control, ~XC_AE); ++ return ((w & XC_AE) == XC_AE); ++} ++ ++static bool ++_dma_alloc(dma_info_t *di, uint direction) ++{ ++ if (DMA64_ENAB(di) && DMA64_MODE(di)) { ++ return dma64_alloc(di, direction); ++ } else if (DMA32_ENAB(di)) { ++ return dma32_alloc(di, direction); ++ } else { ++ ASSERT(0); ++ } ++} ++ ++/* !! may be called with core in reset */ ++static void ++_dma_detach(dma_info_t *di) ++{ ++ ++ DMA_TRACE(("%s: dma_detach\n", di->name)); ++ ++ /* shouldn't be here if descriptors are unreclaimed */ ++ ASSERT(di->txin == di->txout); ++ ASSERT(di->rxin == di->rxout); ++ ++ /* free dma descriptor rings */ ++ if (DMA64_ENAB(di) && DMA64_MODE(di)) { ++ if (di->txd64) { ++ DMA_FREE_CONSISTENT(di->osh, ((int8 *)(uintptr)di->txd64 - di->txdalign), ++ di->txdalloc, (di->txdpaorig), &di->tx_dmah); ++ } ++ if (di->rxd64) { ++ DMA_FREE_CONSISTENT(di->osh, ((int8 *)(uintptr)di->rxd64 - di->rxdalign), ++ di->rxdalloc, (di->rxdpaorig), &di->rx_dmah); ++ } ++ } else if (DMA32_ENAB(di)) { ++ if (di->txd32) { ++ DMA_FREE_CONSISTENT(di->osh, ((int8 *)(uintptr)di->txd32 - di->txdalign), ++ di->txdalloc, (di->txdpaorig), &di->tx_dmah); ++ } ++ if (di->rxd32) { ++ DMA_FREE_CONSISTENT(di->osh, ((int8 *)(uintptr)di->rxd32 - di->rxdalign), ++ di->rxdalloc, (di->rxdpaorig), &di->rx_dmah); ++ } ++ } else ++ ASSERT(0); ++ ++ /* free packet pointer vectors */ ++ if (di->txp) { ++ MFREE(di->osh, (void *)di->txp, (di->ntxd * sizeof(void *))); ++ } ++ if (di->rxp) { ++ MFREE(di->osh, (void *)di->rxp, (di->nrxd * sizeof(void *))); ++ } ++ ++ /* free tx packet DMA handles */ ++ if (di->txp_dmah) { ++ MFREE(di->osh, (void *)di->txp_dmah, di->ntxd * sizeof(hnddma_seg_map_t)); ++ } ++ ++ /* free rx packet DMA handles */ ++ if (di->rxp_dmah) { ++ MFREE(di->osh, (void *)di->rxp_dmah, di->nrxd * sizeof(hnddma_seg_map_t)); ++ } ++ ++ /* free our private info structure */ ++ MFREE(di->osh, (void *)di, sizeof(dma_info_t)); ++ ++} ++ ++static bool ++_dma_descriptor_align(dma_info_t *di) ++{ ++ if (DMA64_ENAB(di) && DMA64_MODE(di)) { ++ uint32 addrl; ++ ++ /* Check to see if the descriptors need to be aligned on 4K/8K or not */ ++ if (di->d64txregs != NULL) { ++ W_REG(di->osh, &di->d64txregs->addrlow, 0xff0); ++ addrl = R_REG(di->osh, &di->d64txregs->addrlow); ++ if (addrl != 0) { ++ return FALSE; ++ } ++ } else if (di->d64rxregs != NULL) { ++ W_REG(di->osh, &di->d64rxregs->addrlow, 0xff0); ++ addrl = R_REG(di->osh, &di->d64rxregs->addrlow); ++ if (addrl != 0) { ++ return FALSE; ++ } ++ } ++ } ++ return TRUE; ++} ++ ++/* return TRUE if this dma engine supports DmaExtendedAddrChanges, otherwise FALSE */ ++static bool ++_dma_isaddrext(dma_info_t *di) ++{ ++ if (DMA64_ENAB(di) && DMA64_MODE(di)) { ++ /* DMA64 supports full 32- or 64-bit operation. AE is always valid */ ++ ++ /* not all tx or rx channel are available */ ++ if (di->d64txregs != NULL) { ++ if (!_dma64_addrext(di->osh, di->d64txregs)) { ++ DMA_ERROR(("%s: _dma_isaddrext: DMA64 tx doesn't have AE set\n", ++ di->name)); ++ ASSERT(0); ++ } ++ return TRUE; ++ } else if (di->d64rxregs != NULL) { ++ if (!_dma64_addrext(di->osh, di->d64rxregs)) { ++ DMA_ERROR(("%s: _dma_isaddrext: DMA64 rx doesn't have AE set\n", ++ di->name)); ++ ASSERT(0); ++ } ++ return TRUE; ++ } ++ return FALSE; ++ } else if (DMA32_ENAB(di)) { ++ if (di->d32txregs) { ++ return (_dma32_addrext(di->osh, di->d32txregs)); ++ } else if (di->d32rxregs) { ++ return (_dma32_addrext(di->osh, di->d32rxregs)); ++ } ++ } else { ++ ASSERT(0); ++ } ++ ++ return FALSE; ++} ++ ++/* initialize descriptor table base address */ ++static void ++_dma_ddtable_init(dma_info_t *di, uint direction, dmaaddr_t pa) ++{ ++ if (DMA64_ENAB(di) && DMA64_MODE(di)) { ++ if (!di->aligndesc_4k) { ++ if (direction == DMA_TX) { ++ di->xmtptrbase = PHYSADDRLO(pa); ++ } else { ++ di->rcvptrbase = PHYSADDRLO(pa); ++ } ++ } ++ ++ if ((di->ddoffsetlow == 0) || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) { ++ if (direction == DMA_TX) { ++ W_REG(di->osh, &di->d64txregs->addrlow, (PHYSADDRLO(pa) + ++ di->ddoffsetlow)); ++ W_REG(di->osh, &di->d64txregs->addrhigh, (PHYSADDRHI(pa) + ++ di->ddoffsethigh)); ++ } else { ++ W_REG(di->osh, &di->d64rxregs->addrlow, (PHYSADDRLO(pa) + ++ di->ddoffsetlow)); ++ W_REG(di->osh, &di->d64rxregs->addrhigh, (PHYSADDRHI(pa) + ++ di->ddoffsethigh)); ++ } ++ } else { ++ /* DMA64 32bits address extension */ ++ uint32 ae; ++ ASSERT(di->addrext); ++ ASSERT(PHYSADDRHI(pa) == 0); ++ ++ /* shift the high bit(s) from pa to ae */ ++ ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; ++ PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH; ++ ++ if (direction == DMA_TX) { ++ W_REG(di->osh, &di->d64txregs->addrlow, (PHYSADDRLO(pa) + ++ di->ddoffsetlow)); ++ W_REG(di->osh, &di->d64txregs->addrhigh, di->ddoffsethigh); ++ SET_REG(di->osh, &di->d64txregs->control, D64_XC_AE, ++ (ae << D64_XC_AE_SHIFT)); ++ } else { ++ W_REG(di->osh, &di->d64rxregs->addrlow, (PHYSADDRLO(pa) + ++ di->ddoffsetlow)); ++ W_REG(di->osh, &di->d64rxregs->addrhigh, di->ddoffsethigh); ++ SET_REG(di->osh, &di->d64rxregs->control, D64_RC_AE, ++ (ae << D64_RC_AE_SHIFT)); ++ } ++ } ++ ++ } else if (DMA32_ENAB(di)) { ++ ASSERT(PHYSADDRHI(pa) == 0); ++ if ((di->ddoffsetlow == 0) || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) { ++ if (direction == DMA_TX) { ++ W_REG(di->osh, &di->d32txregs->addr, (PHYSADDRLO(pa) + ++ di->ddoffsetlow)); ++ } else { ++ W_REG(di->osh, &di->d32rxregs->addr, (PHYSADDRLO(pa) + ++ di->ddoffsetlow)); ++ } ++ } else { ++ /* dma32 address extension */ ++ uint32 ae; ++ ASSERT(di->addrext); ++ ++ /* shift the high bit(s) from pa to ae */ ++ ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; ++ PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH; ++ ++ if (direction == DMA_TX) { ++ W_REG(di->osh, &di->d32txregs->addr, (PHYSADDRLO(pa) + ++ di->ddoffsetlow)); ++ SET_REG(di->osh, &di->d32txregs->control, XC_AE, ae <osh, &di->d32rxregs->addr, (PHYSADDRLO(pa) + ++ di->ddoffsetlow)); ++ SET_REG(di->osh, &di->d32rxregs->control, RC_AE, ae <name)); ++ ++ if (DMA64_ENAB(di) && DMA64_MODE(di)) { ++ OR_REG(di->osh, &di->d64txregs->control, D64_XC_LE); ++ } else if (DMA32_ENAB(di)) { ++ OR_REG(di->osh, &di->d32txregs->control, XC_LE); ++ } else { ++ ASSERT(0); ++ } ++} ++ ++static void ++_dma_rxinit(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_rxinit\n", di->name)); ++ ++ if (di->nrxd == 0) { ++ return; ++ } ++ ++ /* During the reset procedure, the active rxd may not be zero if pktpool is ++ * enabled, we need to reclaim active rxd to avoid rxd being leaked. ++ */ ++ if ((POOL_ENAB(di->pktpool)) && (NRXDACTIVE(di->rxin, di->rxout))) { ++ _dma_rxreclaim(di); ++ } ++ ++ ASSERT(di->rxin == di->rxout); ++ di->rxin = di->rxout = di->rs0cd = 0; ++ ++ /* clear rx descriptor ring */ ++ if (DMA64_ENAB(di) && DMA64_MODE(di)) { ++ BZERO_SM((void *)(uintptr)di->rxd64, (di->nrxd * sizeof(dma64dd_t))); ++ ++ /* DMA engine with out alignment requirement requires table to be inited ++ * before enabling the engine ++ */ ++ if (!di->aligndesc_4k) { ++ _dma_ddtable_init(di, DMA_RX, di->rxdpa); ++ } ++ ++ _dma_rxenable(di); ++ ++ if (di->aligndesc_4k) { ++ _dma_ddtable_init(di, DMA_RX, di->rxdpa); ++ } ++ } else if (DMA32_ENAB(di)) { ++ BZERO_SM((void *)(uintptr)di->rxd32, (di->nrxd * sizeof(dma32dd_t))); ++ _dma_rxenable(di); ++ _dma_ddtable_init(di, DMA_RX, di->rxdpa); ++ } else { ++ ASSERT(0); ++ } ++} ++ ++static void ++_dma_rxenable(dma_info_t *di) ++{ ++ uint dmactrlflags = di->hnddma.dmactrlflags; ++ ++ DMA_TRACE(("%s: dma_rxenable\n", di->name)); ++ ++ if (DMA64_ENAB(di) && DMA64_MODE(di)) { ++ uint32 control = (R_REG(di->osh, &di->d64rxregs->control) & D64_RC_AE) | D64_RC_RE; ++ ++ if ((dmactrlflags & DMA_CTRL_PEN) == 0) { ++ control |= D64_RC_PD; ++ } ++ ++ if (dmactrlflags & DMA_CTRL_ROC) { ++ control |= D64_RC_OC; ++ } ++ ++ /* These bits 20:18 (burstLen) of control register can be written but will take ++ * effect only if these bits are valid. So this will not affect previous versions ++ * of the DMA. They will continue to have those bits set to 0. ++ */ ++ control &= ~D64_RC_BL_MASK; ++ control |= (di->rxburstlen << D64_RC_BL_SHIFT); ++ ++ control &= ~D64_RC_PC_MASK; ++ control |= (di->rxprefetchctl << D64_RC_PC_SHIFT); ++ ++ control &= ~D64_RC_PT_MASK; ++ control |= (di->rxprefetchthresh << D64_RC_PT_SHIFT); ++ ++ W_REG(di->osh, &di->d64rxregs->control, ++ ((di->rxoffset << D64_RC_RO_SHIFT) | control)); ++ } else if (DMA32_ENAB(di)) { ++ uint32 control = (R_REG(di->osh, &di->d32rxregs->control) & RC_AE) | RC_RE; ++ ++ if ((dmactrlflags & DMA_CTRL_PEN) == 0) { ++ control |= RC_PD; ++ } ++ ++ if (dmactrlflags & DMA_CTRL_ROC) { ++ control |= RC_OC; ++ } ++ ++ /* These bits 20:18 (burstLen) of control register can be written but will take ++ * effect only if these bits are valid. So this will not affect previous versions ++ * of the DMA. They will continue to have those bits set to 0. ++ */ ++ control &= ~RC_BL_MASK; ++ control |= (di->rxburstlen << RC_BL_SHIFT); ++ ++ control &= ~RC_PC_MASK; ++ control |= (di->rxprefetchctl << RC_PC_SHIFT); ++ ++ control &= ~RC_PT_MASK; ++ control |= (di->rxprefetchthresh << RC_PT_SHIFT); ++ ++ W_REG(di->osh, &di->d32rxregs->control, ++ ((di->rxoffset << RC_RO_SHIFT) | control)); ++ } else { ++ ASSERT(0); ++ } ++} ++ ++static void ++_dma_rx_param_get(dma_info_t *di, uint16 *rxoffset, uint16 *rxbufsize) ++{ ++ /* the normal values fit into 16 bits */ ++ *rxoffset = (uint16)di->rxoffset; ++ *rxbufsize = (uint16)di->rxbufsize; ++} ++ ++/* !! rx entry routine ++ * returns a pointer to the next frame received, or NULL if there are no more ++ * if DMA_CTRL_RXMULTI is defined, DMA scattering(multiple buffers) is supported ++ * with pkts chain ++ * otherwise, it's treated as giant pkt and will be tossed. ++ * The DMA scattering starts with normal DMA header, followed by first buffer data. ++ * After it reaches the max size of buffer, the data continues in next DMA descriptor ++ * buffer WITHOUT DMA header ++ */ ++static void * BCMFASTPATH ++_dma_rx(dma_info_t *di) ++{ ++ void *p, *head, *tail; ++ uint len; ++ uint pkt_len; ++ int resid = 0; ++#ifdef BCM4335 ++ dma64regs_t *dregs = di->d64rxregs; ++#endif ++ ++next_frame: ++ head = _dma_getnextrxp(di, FALSE); ++ if (head == NULL) { ++ return (NULL); ++ } ++ ++ len = ltoh16(*(uint16 *)(PKTDATA(di->osh, head))); ++ DMA_TRACE(("%s: dma_rx len %d\n", di->name, len)); ++ ++ /* set actual length */ ++ pkt_len = MIN((di->rxoffset + len), di->rxbufsize); ++ PKTSETLEN(di->osh, head, pkt_len); ++ resid = len - (di->rxbufsize - di->rxoffset); ++ ++ /* check for single or multi-buffer rx */ ++ if (resid <= 0) { ++ /* Single frame, all good */ ++ } else if (di->hnddma.dmactrlflags & DMA_CTRL_RXSINGLE) { ++ DMA_TRACE(("%s: dma_rx: corrupted length (%d)\n", di->name, len)); ++ PKTFREE(di->osh, head, FALSE); ++ di->hnddma.rxgiants++; ++ goto next_frame; ++ } else { ++ /* multi-buffer rx */ ++#ifdef BCMDBG ++ p = NULL; /* get rid of compiler warning */ ++#endif /* BCMDBG */ ++ tail = head; ++ while ((resid > 0) && (p = _dma_getnextrxp(di, FALSE))) { ++ PKTSETNEXT(di->osh, tail, p); ++ pkt_len = MIN(resid, (int)di->rxbufsize); ++ PKTSETLEN(di->osh, p, pkt_len); ++ ++ tail = p; ++ resid -= di->rxbufsize; ++ } ++ ++#ifdef BCMDBG ++ if (resid > 0) { ++ uint16 cur; ++ ASSERT(p == NULL); ++ cur = (DMA64_ENAB(di) && DMA64_MODE(di)) ? ++ B2I(((R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_CD_MASK) - ++ di->rcvptrbase) & D64_RS0_CD_MASK, dma64dd_t) : ++ B2I(R_REG(di->osh, &di->d32rxregs->status) & RS_CD_MASK, ++ dma32dd_t); ++ DMA_ERROR(("_dma_rx, rxin %d rxout %d, hw_curr %d\n", ++ di->rxin, di->rxout, cur)); ++ } ++#endif /* BCMDBG */ ++ ++ if ((di->hnddma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) { ++ DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", di->name, len)); ++ PKTFREE(di->osh, head, FALSE); ++ di->hnddma.rxgiants++; ++ goto next_frame; ++ } ++ } ++ ++ return (head); ++} ++ ++/* post receive buffers ++ * return FALSE is refill failed completely and ring is empty ++ * this will stall the rx dma and user might want to call rxfill again asap ++ * This unlikely happens on memory-rich NIC, but often on memory-constrained dongle ++ */ ++static bool BCMFASTPATH ++_dma_rxfill(dma_info_t *di) ++{ ++ void *p; ++ uint16 rxin, rxout; ++ uint32 flags = 0; ++ uint n; ++ uint i; ++ dmaaddr_t pa; ++ uint extra_offset = 0, extra_pad; ++ bool ring_empty; ++ uint alignment_req = (di->hnddma.dmactrlflags & DMA_CTRL_USB_BOUNDRY4KB_WAR) ? ++ 16 : 1; /* MUST BE POWER of 2 */ ++ ++ ring_empty = FALSE; ++ ++ /* ++ * Determine how many receive buffers we're lacking ++ * from the full complement, allocate, initialize, ++ * and post them, then update the chip rx lastdscr. ++ */ ++ ++ rxin = di->rxin; ++ rxout = di->rxout; ++ ++ n = di->nrxpost - NRXDACTIVE(rxin, rxout); ++ ++ if (di->rxbufsize > BCMEXTRAHDROOM) { ++ extra_offset = di->rxextrahdrroom; ++ } ++ ++ DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n)); ++ ++ for (i = 0; i < n; i++) { ++ /* the di->rxbufsize doesn't include the extra headroom, we need to add it to the ++ size to be allocated ++ */ ++ if (POOL_ENAB(di->pktpool)) { ++ ASSERT(di->pktpool); ++ p = pktpool_get(di->pktpool); ++#ifdef BCMDBG_POOL ++ if (p) { ++ PKTPOOLSETSTATE(p, POOL_RXFILL); ++ } ++#endif /* BCMDBG_POOL */ ++ } ++ else { ++ p = PKTGET(di->osh, (di->rxbufsize + extra_offset + alignment_req - 1), FALSE); ++ } ++ if (p == NULL) { ++ DMA_TRACE(("%s: dma_rxfill: out of rxbufs\n", di->name)); ++ if (i == 0) { ++ if (DMA64_ENAB(di) && DMA64_MODE(di)) { ++ if (dma64_rxidle(di)) { ++ DMA_TRACE(("%s: rxfill64: ring is empty !\n", di->name)); ++ ring_empty = TRUE; ++ } ++ } else if (DMA32_ENAB(di)) { ++ if (dma32_rxidle(di)) { ++ DMA_TRACE(("%s: rxfill32: ring is empty !\n", di->name)); ++ ring_empty = TRUE; ++ } ++ } else { ++ ASSERT(0); ++ } ++ } ++ di->hnddma.rxnobuf++; ++ break; ++ } ++ /* reserve an extra headroom, if applicable */ ++ if (di->hnddma.dmactrlflags & DMA_CTRL_USB_BOUNDRY4KB_WAR) { ++ extra_pad = ((alignment_req - (uint)(((unsigned long)PKTDATA(di->osh, p) - ++ (unsigned long)(uchar *)0))) & (alignment_req - 1)); ++ } else { ++ extra_pad = 0; ++ } ++ ++ if (extra_offset + extra_pad) { ++ PKTPULL(di->osh, p, extra_offset + extra_pad); ++ } ++ ++ /* Do a cached write instead of uncached write since DMA_MAP ++ * will flush the cache. ++ */ ++ *(uint16 *)(PKTDATA(di->osh, p)) = 0; ++ ++ if (DMASGLIST_ENAB) { ++ bzero(&di->rxp_dmah[rxout], sizeof(hnddma_seg_map_t)); ++ } ++ ++#if defined(CONFIG_BCM_IPROC_GMAC_ACP) && !defined(BCMDMASGLISTOSL) ++ pa = virt_to_phys(PKTDATA(di->osh, p)); ++#else ++ pa = DMA_MAP(di->osh, PKTDATA(di->osh, p), ++ di->rxbufsize, DMA_RX, p, ++ &di->rxp_dmah[rxout]); ++#endif /* defined(CONFIG_BCM_IPROC_GMAC_ACP) && !defined(BCMDMASGLISTOSL) */ ++ ++ ASSERT(ISALIGNED(PHYSADDRLO(pa), 4)); ++ ++ /* save the free packet pointer */ ++ ASSERT(di->rxp[rxout] == NULL); ++ di->rxp[rxout] = p; ++ ++ /* reset flags for each descriptor */ ++ flags = 0; ++ if (DMA64_ENAB(di) && DMA64_MODE(di)) { ++ if (rxout == (di->nrxd - 1)) { ++ flags = D64_CTRL1_EOT; ++ } ++ ++ dma64_dd_upd(di, di->rxd64, pa, rxout, &flags, di->rxbufsize); ++ } else if (DMA32_ENAB(di)) { ++ if (rxout == (di->nrxd - 1)) { ++ flags = CTRL_EOT; ++ } ++ ++ ASSERT(PHYSADDRHI(pa) == 0); ++ dma32_dd_upd(di, di->rxd32, pa, rxout, &flags, di->rxbufsize); ++ } else { ++ ASSERT(0); ++ } ++ rxout = NEXTRXD(rxout); ++ } ++ ++ di->rxout = rxout; ++ ++ /* update the chip lastdscr pointer */ ++ if (DMA64_ENAB(di) && DMA64_MODE(di)) { ++ W_REG(di->osh, &di->d64rxregs->ptr, di->rcvptrbase + I2B(rxout, dma64dd_t)); ++ } else if (DMA32_ENAB(di)) { ++ W_REG(di->osh, &di->d32rxregs->ptr, I2B(rxout, dma32dd_t)); ++ } else { ++ ASSERT(0); ++ } ++ ++ return ring_empty; ++} ++ ++/* like getnexttxp but no reclaim */ ++static void * ++_dma_peeknexttxp(dma_info_t *di) ++{ ++ uint16 end, i; ++ ++ if (di->ntxd == 0) { ++ return (NULL); ++ } ++ ++ if (DMA64_ENAB(di) && DMA64_MODE(di)) { ++ end = (uint16)B2I(((R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_CD_MASK) - ++ di->xmtptrbase) & D64_XS0_CD_MASK, dma64dd_t); ++ di->xs0cd = end; ++ } else if (DMA32_ENAB(di)) { ++ end = (uint16)B2I(R_REG(di->osh, &di->d32txregs->status) & XS_CD_MASK, dma32dd_t); ++ di->xs0cd = end; ++ } else { ++ ASSERT(0); ++ } ++ ++ for (i = di->txin; i != end; i = NEXTTXD(i)) { ++ if (di->txp[i]) { ++ return (di->txp[i]); ++ } ++ } ++ ++ return (NULL); ++} ++ ++int ++_dma_peekntxp(dma_info_t *di, int *len, void *txps[], txd_range_t range) ++{ ++ uint16 start, end, i; ++ uint act; ++ void *txp = NULL; ++ int k, len_max; ++ ++ DMA_TRACE(("%s: dma_peekntxp\n", di->name)); ++ ++ ASSERT(len); ++ ASSERT(txps); ++ ASSERT(di); ++ if (di->ntxd == 0) { ++ *len = 0; ++ return BCME_ERROR; ++ } ++ ++ len_max = *len; ++ *len = 0; ++ ++ start = di->txin; ++ ++ if (range == HNDDMA_RANGE_ALL) { ++ end = di->txout; ++ } else { ++ if (DMA64_ENAB(di)) { ++ end = B2I(((R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_CD_MASK) - ++ di->xmtptrbase) & D64_XS0_CD_MASK, dma64dd_t); ++ ++ act = (uint)(R_REG(di->osh, &di->d64txregs->status1) & D64_XS1_AD_MASK); ++ act = (act - di->xmtptrbase) & D64_XS0_CD_MASK; ++ act = (uint)B2I(act, dma64dd_t); ++ } else { ++ end = B2I(R_REG(di->osh, &di->d32txregs->status) & XS_CD_MASK, dma32dd_t); ++ ++ act = (uint)((R_REG(di->osh, &di->d32txregs->status) & XS_AD_MASK) >> ++ XS_AD_SHIFT); ++ act = (uint)B2I(act, dma32dd_t); ++ } ++ ++ di->xs0cd = end; ++ if (end != act) { ++ end = PREVTXD(act); ++ } ++ } ++ ++ if ((start == 0) && (end > di->txout)) { ++ return BCME_ERROR; ++ } ++ ++ k = 0; ++ for (i = start; i != end; i = NEXTTXD(i)) { ++ txp = di->txp[i]; ++ if (txp != NULL) { ++ if (k < len_max) { ++ txps[k++] = txp; ++ } else { ++ break; ++ } ++ } ++ } ++ *len = k; ++ ++ return BCME_OK; ++} ++ ++/* like getnextrxp but not take off the ring */ ++static void * ++_dma_peeknextrxp(dma_info_t *di) ++{ ++ uint16 end, i; ++ ++ if (di->nrxd == 0) { ++ return (NULL); ++ } ++ ++ if (DMA64_ENAB(di) && DMA64_MODE(di)) { ++ end = (uint16)B2I(((R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_CD_MASK) - ++ di->rcvptrbase) & D64_RS0_CD_MASK, dma64dd_t); ++ di->rs0cd = end; ++ } else if (DMA32_ENAB(di)) { ++ end = (uint16)B2I(R_REG(di->osh, &di->d32rxregs->status) & RS_CD_MASK, dma32dd_t); ++ di->rs0cd = end; ++ } else { ++ ASSERT(0); ++ } ++ ++ for (i = di->rxin; i != end; i = NEXTRXD(i)) { ++ if (di->rxp[i]) { ++ return (di->rxp[i]); ++ } ++ } ++ ++ return (NULL); ++} ++ ++static void ++_dma_rxreclaim(dma_info_t *di) ++{ ++ void *p; ++ bool origcb = TRUE; ++ ++#ifndef EFI ++ /* "unused local" warning suppression for OSLs that ++ * define PKTFREE() without using the di->osh arg ++ */ ++ di = di; ++#endif /* EFI */ ++ ++ DMA_TRACE(("%s: dma_rxreclaim\n", di->name)); ++ ++ if (POOL_ENAB(di->pktpool) && ++ ((origcb = pktpool_emptycb_disabled(di->pktpool)) == FALSE)) { ++ pktpool_emptycb_disable(di->pktpool, TRUE); ++ } ++ ++ while ((p = _dma_getnextrxp(di, TRUE))) { ++ PKTFREE(di->osh, p, FALSE); ++ } ++ ++ if (origcb == FALSE) { ++ pktpool_emptycb_disable(di->pktpool, FALSE); ++ } ++} ++ ++static void * BCMFASTPATH ++_dma_getnextrxp(dma_info_t *di, bool forceall) ++{ ++ if (di->nrxd == 0) { ++ return (NULL); ++ } ++ ++ if (DMA64_ENAB(di) && DMA64_MODE(di)) { ++ return dma64_getnextrxp(di, forceall); ++ } else if (DMA32_ENAB(di)) { ++ return dma32_getnextrxp(di, forceall); ++ } else { ++ ASSERT(0); ++ } ++} ++ ++static void ++_dma_txblock(dma_info_t *di) ++{ ++ di->hnddma.txavail = 0; ++} ++ ++static void ++_dma_txunblock(dma_info_t *di) ++{ ++ di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++} ++ ++static uint ++_dma_txactive(dma_info_t *di) ++{ ++ return NTXDACTIVE(di->txin, di->txout); ++} ++ ++static uint ++_dma_txpending(dma_info_t *di) ++{ ++ uint16 curr; ++ ++ if (DMA64_ENAB(di) && DMA64_MODE(di)) { ++ curr = B2I(((R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_CD_MASK) - ++ di->xmtptrbase) & D64_XS0_CD_MASK, dma64dd_t); ++ di->xs0cd = curr; ++ } else if (DMA32_ENAB(di)) { ++ curr = B2I(R_REG(di->osh, &di->d32txregs->status) & XS_CD_MASK, dma32dd_t); ++ di->xs0cd = curr; ++ } else { ++ ASSERT(0); ++ } ++ ++ return NTXDACTIVE(curr, di->txout); ++} ++ ++static uint ++_dma_txcommitted(dma_info_t *di) ++{ ++ uint16 ptr; ++ uint txin = di->txin; ++ ++ if (txin == di->txout) { ++ return 0; ++ } ++ ++ if (DMA64_ENAB(di) && DMA64_MODE(di)) { ++ ptr = B2I(R_REG(di->osh, &di->d64txregs->ptr), dma64dd_t); ++ } else if (DMA32_ENAB(di)) { ++ ptr = B2I(R_REG(di->osh, &di->d32txregs->ptr), dma32dd_t); ++ } else { ++ ASSERT(0); ++ } ++ ++ return NTXDACTIVE(di->txin, ptr); ++} ++ ++static uint ++_dma_rxactive(dma_info_t *di) ++{ ++ return NRXDACTIVE(di->rxin, di->rxout); ++} ++ ++static uint ++_dma_activerxbuf(dma_info_t *di) ++{ ++ uint16 curr, ptr; ++ curr = B2I(((R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_CD_MASK) - ++ di->rcvptrbase) & D64_RS0_CD_MASK, dma64dd_t); ++ ptr = B2I(((R_REG(di->osh, &di->d64rxregs->ptr) & D64_RS0_CD_MASK) - ++ di->rcvptrbase) & D64_RS0_CD_MASK, dma64dd_t); ++ return NRXDACTIVE(curr, ptr); ++} ++ ++ ++static void ++_dma_counterreset(dma_info_t *di) ++{ ++ /* reset all software counter */ ++ di->hnddma.rxgiants = 0; ++ di->hnddma.rxnobuf = 0; ++ di->hnddma.txnobuf = 0; ++} ++ ++static uint ++_dma_ctrlflags(dma_info_t *di, uint mask, uint flags) ++{ ++ uint dmactrlflags; ++ ++ if (!di) { ++ DMA_ERROR(("_dma_ctrlflags: NULL dma handle\n")); ++ return (0); ++ } ++ ++ dmactrlflags = di->hnddma.dmactrlflags; ++ ASSERT((flags & ~mask) == 0); ++ ++ dmactrlflags &= ~mask; ++ dmactrlflags |= flags; ++ ++ /* If trying to enable parity, check if parity is actually supported */ ++ if (dmactrlflags & DMA_CTRL_PEN) { ++ uint32 control; ++ ++ if (DMA64_ENAB(di) && DMA64_MODE(di)) { ++ control = R_REG(di->osh, &di->d64txregs->control); ++ W_REG(di->osh, &di->d64txregs->control, control | D64_XC_PD); ++ if (R_REG(di->osh, &di->d64txregs->control) & D64_XC_PD) { ++ /* We *can* disable it so it is supported, ++ * restore control register ++ */ ++ W_REG(di->osh, &di->d64txregs->control, control); ++ } else { ++ /* Not supported, don't allow it to be enabled */ ++ dmactrlflags &= ~DMA_CTRL_PEN; ++ } ++ } else if (DMA32_ENAB(di)) { ++ control = R_REG(di->osh, &di->d32txregs->control); ++ W_REG(di->osh, &di->d32txregs->control, control | XC_PD); ++ if (R_REG(di->osh, &di->d32txregs->control) & XC_PD) { ++ W_REG(di->osh, &di->d32txregs->control, control); ++ } else { ++ /* Not supported, don't allow it to be enabled */ ++ dmactrlflags &= ~DMA_CTRL_PEN; ++ } ++ } else { ++ ASSERT(0); ++ } ++ } ++ ++ di->hnddma.dmactrlflags = dmactrlflags; ++ ++ return (dmactrlflags); ++} ++ ++/* get the address of the var in order to change later */ ++static uintptr ++_dma_getvar(dma_info_t *di, const char *name) ++{ ++ if (!strcmp(name, "&txavail")) { ++ return ((uintptr) &(di->hnddma.txavail)); ++ } else { ++ ASSERT(0); ++ } ++ return (0); ++} ++ ++static uint ++_dma_avoidancecnt(dma_info_t *di) ++{ ++ return (di->dma_avoidance_cnt); ++} ++ ++void ++dma_txpioloopback(osl_t *osh, dma32regs_t *regs) ++{ ++ OR_REG(osh, ®s->control, XC_LE); ++} ++ ++static ++uint8 dma_align_sizetobits(uint size) ++{ ++ uint8 bitpos = 0; ++ ASSERT(size); ++ ASSERT(!(size & (size-1))); ++ while (size >>= 1) { ++ bitpos ++; ++ } ++ return (bitpos); ++} ++ ++/* This function ensures that the DMA descriptor ring will not get allocated ++ * across Page boundary. If the allocation is done across the page boundary ++ * at the first time, then it is freed and the allocation is done at ++ * descriptor ring size aligned location. This will ensure that the ring will ++ * not cross page boundary ++ */ ++static void * ++dma_ringalloc(osl_t *osh, uint32 boundary, uint size, uint16 *alignbits, uint* alloced, ++ dmaaddr_t *descpa, osldma_t **dmah) ++{ ++ void * va; ++ uint32 desc_strtaddr; ++ uint32 alignbytes = 1 << *alignbits; ++ ++ if ((va = DMA_ALLOC_CONSISTENT(osh, size, *alignbits, alloced, descpa, dmah)) == NULL) { ++ return NULL; ++ } ++ ++ /* printk("%s va(0x%x)\n", __FUNCTION__, va); */ ++ desc_strtaddr = (uint32)ROUNDUP((uint)PHYSADDRLO(*descpa), alignbytes); ++ if (((desc_strtaddr + size - 1) & boundary) != ++ (desc_strtaddr & boundary)) { ++ *alignbits = dma_align_sizetobits(size); ++ DMA_FREE_CONSISTENT(osh, va, ++ size, *descpa, dmah); ++ va = DMA_ALLOC_CONSISTENT(osh, size, *alignbits, alloced, descpa, dmah); ++ } ++ return va; ++} ++ ++#if defined(BCMDBG) ++static void ++dma32_dumpring(dma_info_t *di, struct bcmstrbuf *b, dma32dd_t *ring, uint start, uint end, ++ uint max_num) ++{ ++ uint i; ++ ++ for (i = start; i != end; i = XXD((i + 1), max_num)) { ++ /* in the format of high->low 8 bytes */ ++ bcm_bprintf(b, "ring index %d: 0x%x %x\n", ++ i, R_SM(&ring[i].addr), R_SM(&ring[i].ctrl)); ++ } ++} ++ ++static void ++dma32_dumptx(dma_info_t *di, struct bcmstrbuf *b, bool dumpring) ++{ ++ if (di->ntxd == 0) { ++ return; ++ } ++ ++ bcm_bprintf(b, "DMA32: txd32 %p txdpa 0x%lx txp %p txin %d txout %d " ++ "txavail %d txnodesc %d\n", di->txd32, PHYSADDRLO(di->txdpa), di->txp, di->txin, ++ di->txout, di->hnddma.txavail, di->hnddma.txnodesc); ++ ++ bcm_bprintf(b, "xmtcontrol 0x%x xmtaddr 0x%x xmtptr 0x%x xmtstatus 0x%x\n", ++ R_REG(di->osh, &di->d32txregs->control), ++ R_REG(di->osh, &di->d32txregs->addr), ++ R_REG(di->osh, &di->d32txregs->ptr), ++ R_REG(di->osh, &di->d32txregs->status)); ++ ++ if (dumpring && di->txd32) { ++ dma32_dumpring(di, b, di->txd32, di->txin, di->txout, di->ntxd); ++ } ++} ++ ++static void ++dma32_dumprx(dma_info_t *di, struct bcmstrbuf *b, bool dumpring) ++{ ++ if (di->nrxd == 0) { ++ return; ++ } ++ ++ bcm_bprintf(b, "DMA32: rxd32 %p rxdpa 0x%lx rxp %p rxin %d rxout %d\n", ++ di->rxd32, PHYSADDRLO(di->rxdpa), di->rxp, di->rxin, di->rxout); ++ ++ bcm_bprintf(b, "rcvcontrol 0x%x rcvaddr 0x%x rcvptr 0x%x rcvstatus 0x%x\n", ++ R_REG(di->osh, &di->d32rxregs->control), ++ R_REG(di->osh, &di->d32rxregs->addr), ++ R_REG(di->osh, &di->d32rxregs->ptr), ++ R_REG(di->osh, &di->d32rxregs->status)); ++ if (di->rxd32 && dumpring) { ++ dma32_dumpring(di, b, di->rxd32, di->rxin, di->rxout, di->nrxd); ++ } ++} ++ ++static void ++dma32_dump(dma_info_t *di, struct bcmstrbuf *b, bool dumpring) ++{ ++ dma32_dumptx(di, b, dumpring); ++ dma32_dumprx(di, b, dumpring); ++} ++ ++static void ++dma64_dumpring(dma_info_t *di, struct bcmstrbuf *b, dma64dd_t *ring, uint start, uint end, ++ uint max_num) ++{ ++ uint i; ++ ++ for (i = start; i != end; i = XXD((i + 1), max_num)) { ++ /* in the format of high->low 16 bytes */ ++ bcm_bprintf(b, "ring index %d: 0x%x %x %x %x\n", ++ i, R_SM(&ring[i].addrhigh), R_SM(&ring[i].addrlow), ++ R_SM(&ring[i].ctrl2), R_SM(&ring[i].ctrl1)); ++ } ++} ++ ++static void ++dma64_dumptx(dma_info_t *di, struct bcmstrbuf *b, bool dumpring) ++{ ++ if (di->ntxd == 0) { ++ return; ++ } ++ ++ bcm_bprintf(b, "DMA64: txd64 %p txdpa 0x%lx txdpahi 0x%lx txp %p txin %d txout %d " ++ "txavail %d txnodesc %d\n", di->txd64, PHYSADDRLO(di->txdpa), ++ PHYSADDRHI(di->txdpaorig), di->txp, di->txin, di->txout, di->hnddma.txavail, ++ di->hnddma.txnodesc); ++ ++ bcm_bprintf(b, "xmtcontrol 0x%x xmtaddrlow 0x%x xmtaddrhigh 0x%x " ++ "xmtptr 0x%x xmtstatus0 0x%x xmtstatus1 0x%x\n", ++ R_REG(di->osh, &di->d64txregs->control), ++ R_REG(di->osh, &di->d64txregs->addrlow), ++ R_REG(di->osh, &di->d64txregs->addrhigh), ++ R_REG(di->osh, &di->d64txregs->ptr), ++ R_REG(di->osh, &di->d64txregs->status0), ++ R_REG(di->osh, &di->d64txregs->status1)); ++ ++ bcm_bprintf(b, "DMA64: DMA avoidance applied %d\n", di->dma_avoidance_cnt); ++ ++ if (dumpring && di->txd64) { ++ dma64_dumpring(di, b, di->txd64, di->txin, di->txout, di->ntxd); ++ } ++} ++ ++static void ++dma64_dumprx(dma_info_t *di, struct bcmstrbuf *b, bool dumpring) ++{ ++ if (di->nrxd == 0) { ++ return; ++ } ++ ++ bcm_bprintf(b, "DMA64: rxd64 %p rxdpa 0x%lx rxdpahi 0x%lx rxp %p rxin %d rxout %d\n", ++ di->rxd64, PHYSADDRLO(di->rxdpa), PHYSADDRHI(di->rxdpaorig), di->rxp, ++ di->rxin, di->rxout); ++ ++ bcm_bprintf(b, "rcvcontrol 0x%x rcvaddrlow 0x%x rcvaddrhigh 0x%x rcvptr " ++ "0x%x rcvstatus0 0x%x rcvstatus1 0x%x\n", ++ R_REG(di->osh, &di->d64rxregs->control), ++ R_REG(di->osh, &di->d64rxregs->addrlow), ++ R_REG(di->osh, &di->d64rxregs->addrhigh), ++ R_REG(di->osh, &di->d64rxregs->ptr), ++ R_REG(di->osh, &di->d64rxregs->status0), ++ R_REG(di->osh, &di->d64rxregs->status1)); ++ if (di->rxd64 && dumpring) { ++ dma64_dumpring(di, b, di->rxd64, di->rxin, di->rxout, di->nrxd); ++ } ++} ++ ++static void ++dma64_dump(dma_info_t *di, struct bcmstrbuf *b, bool dumpring) ++{ ++ dma64_dumptx(di, b, dumpring); ++ dma64_dumprx(di, b, dumpring); ++} ++#endif ++ ++ ++/* 32-bit DMA functions */ ++ ++static void ++dma32_txinit(dma_info_t *di) ++{ ++ uint32 control = XC_XE; ++ ++ DMA_TRACE(("%s: dma_txinit\n", di->name)); ++ ++ if (di->ntxd == 0) { ++ return; ++ } ++ ++ di->txin = di->txout = di->xs0cd = 0; ++ di->hnddma.txavail = di->ntxd - 1; ++ ++ /* clear tx descriptor ring */ ++ BZERO_SM(DISCARD_QUAL(di->txd32, void), (di->ntxd * sizeof(dma32dd_t))); ++ ++ /* These bits 20:18 (burstLen) of control register can be written but will take ++ * effect only if these bits are valid. So this will not affect previous versions ++ * of the DMA. They will continue to have those bits set to 0. ++ */ ++ control |= (di->txburstlen << XC_BL_SHIFT); ++ control |= (di->txmultioutstdrd << XC_MR_SHIFT); ++ control |= (di->txprefetchctl << XC_PC_SHIFT); ++ control |= (di->txprefetchthresh << XC_PT_SHIFT); ++ ++ if ((di->hnddma.dmactrlflags & DMA_CTRL_PEN) == 0) { ++ control |= XC_PD; ++ } ++ W_REG(di->osh, &di->d32txregs->control, control); ++ _dma_ddtable_init(di, DMA_TX, di->txdpa); ++} ++ ++static bool ++dma32_txenabled(dma_info_t *di) ++{ ++ uint32 xc; ++ ++ /* If the chip is dead, it is not enabled :-) */ ++ xc = R_REG(di->osh, &di->d32txregs->control); ++ return ((xc != 0xffffffff) && (xc & XC_XE)); ++} ++ ++static void ++dma32_txsuspend(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_txsuspend\n", di->name)); ++ ++ if (di->ntxd == 0) { ++ return; ++ } ++ ++ OR_REG(di->osh, &di->d32txregs->control, XC_SE); ++} ++ ++static void ++dma32_txresume(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_txresume\n", di->name)); ++ ++ if (di->ntxd == 0) { ++ return; ++ } ++ ++ AND_REG(di->osh, &di->d32txregs->control, ~XC_SE); ++} ++ ++static bool ++dma32_txsuspended(dma_info_t *di) ++{ ++ return (di->ntxd == 0) || ((R_REG(di->osh, &di->d32txregs->control) & XC_SE) == XC_SE); ++} ++ ++#ifdef WL_MULTIQUEUE ++static void ++dma32_txflush(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_txflush\n", di->name)); ++ ++ if (di->ntxd == 0) { ++ return; ++ } ++ ++ OR_REG(di->osh, &di->d32txregs->control, XC_SE | XC_FL); ++} ++ ++static void ++dma32_txflush_clear(dma_info_t *di) ++{ ++ uint32 status; ++ ++ DMA_TRACE(("%s: dma_txflush_clear\n", di->name)); ++ ++ if (di->ntxd == 0) { ++ return; ++ } ++ ++ SPINWAIT(((status = (R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK)) ++ != XS_XS_DISABLED) && ++ (status != XS_XS_IDLE) && ++ (status != XS_XS_STOPPED), ++ (10000)); ++ AND_REG(di->osh, &di->d32txregs->control, ~XC_FL); ++} ++#endif /* WL_MULTIQUEUE */ ++ ++static void ++dma32_txreclaim(dma_info_t *di, txd_range_t range) ++{ ++ void *p; ++ ++ DMA_TRACE(("%s: dma_txreclaim %s\n", di->name, ++ (range == HNDDMA_RANGE_ALL) ? "all" : ++ ((range == HNDDMA_RANGE_TRANSMITTED) ? "transmitted" : "transfered"))); ++ ++ if (di->txin == di->txout) { ++ return; ++ } ++ ++ while ((p = dma32_getnexttxp(di, range))) { ++ PKTFREE(di->osh, p, TRUE); ++ } ++} ++ ++static bool ++dma32_txstopped(dma_info_t *di) ++{ ++ return ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) == XS_XS_STOPPED); ++} ++ ++static bool ++dma32_rxstopped(dma_info_t *di) ++{ ++ return ((R_REG(di->osh, &di->d32rxregs->status) & RS_RS_MASK) == RS_RS_STOPPED); ++} ++ ++static bool ++dma32_alloc(dma_info_t *di, uint direction) ++{ ++ uint size; ++ uint ddlen; ++ void *va; ++ uint alloced; ++ uint16 align; ++ uint16 align_bits; ++ ++ ddlen = sizeof(dma32dd_t); ++ ++ size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen); ++ ++ alloced = 0; ++ align_bits = di->dmadesc_align; ++ align = (1 << align_bits); ++ ++ if (direction == DMA_TX) { ++ if ((va = dma_ringalloc(di->osh, D32RINGALIGN, size, &align_bits, &alloced, ++ &di->txdpaorig, &di->tx_dmah)) == NULL) { ++ DMA_ERROR(("%s: dma_alloc: DMA_ALLOC_CONSISTENT(ntxd) failed\n", ++ di->name)); ++ return FALSE; ++ } ++ ++ PHYSADDRHISET(di->txdpa, 0); ++ ASSERT(PHYSADDRHI(di->txdpaorig) == 0); ++ di->txd32 = (dma32dd_t *)ROUNDUP((uintptr)va, align); ++ di->txdalign = (uint)((int8 *)(uintptr)di->txd32 - (int8 *)va); ++ ++ PHYSADDRLOSET(di->txdpa, PHYSADDRLO(di->txdpaorig) + di->txdalign); ++ /* Make sure that alignment didn't overflow */ ++ ASSERT(PHYSADDRLO(di->txdpa) >= PHYSADDRLO(di->txdpaorig)); ++ ++ di->txdalloc = alloced; ++ ASSERT(ISALIGNED(di->txd32, align)); ++ } else { ++ if ((va = dma_ringalloc(di->osh, D32RINGALIGN, size, &align_bits, &alloced, ++ &di->rxdpaorig, &di->rx_dmah)) == NULL) { ++ DMA_ERROR(("%s: dma_alloc: DMA_ALLOC_CONSISTENT(nrxd) failed\n", ++ di->name)); ++ return FALSE; ++ } ++ ++ PHYSADDRHISET(di->rxdpa, 0); ++ ASSERT(PHYSADDRHI(di->rxdpaorig) == 0); ++ di->rxd32 = (dma32dd_t *)ROUNDUP((uintptr)va, align); ++ di->rxdalign = (uint)((int8 *)(uintptr)di->rxd32 - (int8 *)va); ++ ++ PHYSADDRLOSET(di->rxdpa, PHYSADDRLO(di->rxdpaorig) + di->rxdalign); ++ /* Make sure that alignment didn't overflow */ ++ ASSERT(PHYSADDRLO(di->rxdpa) >= PHYSADDRLO(di->rxdpaorig)); ++ di->rxdalloc = alloced; ++ ASSERT(ISALIGNED(di->rxd32, align)); ++ } ++ ++ return TRUE; ++} ++ ++static bool ++dma32_txreset(dma_info_t *di) ++{ ++ uint32 status; ++ ++ if (di->ntxd == 0) { ++ return TRUE; ++ } ++ ++ /* suspend tx DMA first */ ++ W_REG(di->osh, &di->d32txregs->control, XC_SE); ++ SPINWAIT(((status = (R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK)) ++ != XS_XS_DISABLED) && ++ (status != XS_XS_IDLE) && ++ (status != XS_XS_STOPPED), ++ (10000)); ++ ++ W_REG(di->osh, &di->d32txregs->control, 0); ++ SPINWAIT(((status = (R_REG(di->osh, ++ &di->d32txregs->status) & XS_XS_MASK)) != XS_XS_DISABLED), ++ 10000); ++ ++ /* We should be disabled at this point */ ++ if (status != XS_XS_DISABLED) { ++ DMA_ERROR(("%s: status != D64_XS0_XS_DISABLED 0x%x\n", __FUNCTION__, status)); ++ ASSERT(status == XS_XS_DISABLED); ++ OSL_DELAY(300); ++ } ++ ++ return (status == XS_XS_DISABLED); ++} ++ ++static bool ++dma32_rxidle(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_rxidle\n", di->name)); ++ ++ if (di->nrxd == 0) { ++ return TRUE; ++ } ++ ++ return ((R_REG(di->osh, &di->d32rxregs->status) & RS_CD_MASK) == ++ R_REG(di->osh, &di->d32rxregs->ptr)); ++} ++ ++static bool ++dma32_rxreset(dma_info_t *di) ++{ ++ uint32 status; ++ ++ if (di->nrxd == 0) { ++ return TRUE; ++ } ++ ++ W_REG(di->osh, &di->d32rxregs->control, 0); ++ SPINWAIT(((status = (R_REG(di->osh, ++ &di->d32rxregs->status) & RS_RS_MASK)) != RS_RS_DISABLED), ++ 10000); ++ ++ return (status == RS_RS_DISABLED); ++} ++ ++static bool ++dma32_rxenabled(dma_info_t *di) ++{ ++ uint32 rc; ++ ++ rc = R_REG(di->osh, &di->d32rxregs->control); ++ return ((rc != 0xffffffff) && (rc & RC_RE)); ++} ++ ++static bool ++dma32_txsuspendedidle(dma_info_t *di) ++{ ++ if (di->ntxd == 0) { ++ return TRUE; ++ } ++ ++ if (!(R_REG(di->osh, &di->d32txregs->control) & XC_SE)) { ++ return 0; ++ } ++ ++ if ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) != XS_XS_IDLE) { ++ return 0; ++ } ++ ++ OSL_DELAY(2); ++ return ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) == XS_XS_IDLE); ++} ++ ++/* !! tx entry routine ++ * supports full 32bit dma engine buffer addressing so ++ * dma buffers can cross 4 Kbyte page boundaries. ++ * ++ * WARNING: call must check the return value for error. ++ * the error(toss frames) could be fatal and cause many subsequent hard to debug problems ++ */ ++static int ++dma32_txfast(dma_info_t *di, void *p0, bool commit) ++{ ++ void *p, *next; ++ uchar *data; ++ uint len; ++ uint16 txout; ++ uint32 flags = 0; ++ dmaaddr_t pa; ++ ++ DMA_TRACE(("%s: dma_txfast\n", di->name)); ++ ++ txout = di->txout; ++ ++ /* ++ * Walk the chain of packet buffers ++ * allocating and initializing transmit descriptor entries. ++ */ ++ for (p = p0; p; p = next) { ++ uint nsegs, j; ++ hnddma_seg_map_t *map; ++ ++ data = PKTDATA(di->osh, p); ++ len = PKTLEN(di->osh, p); ++#ifdef BCM_DMAPAD ++ len += PKTDMAPAD(di->osh, p); ++#endif ++ next = PKTNEXT(di->osh, p); ++ ++ /* return nonzero if out of tx descriptors */ ++ if (NEXTTXD(txout) == di->txin) { ++ goto outoftxd; ++ } ++ ++ if (len == 0) { ++ continue; ++ } ++ ++ if (DMASGLIST_ENAB) { ++ bzero(&di->txp_dmah[txout], sizeof(hnddma_seg_map_t)); ++ } ++ ++ /* get physical address of buffer start */ ++ pa = DMA_MAP(di->osh, data, len, DMA_TX, p, &di->txp_dmah[txout]); ++ ++ if (DMASGLIST_ENAB) { ++ map = &di->txp_dmah[txout]; ++ ++ /* See if all the segments can be accounted for */ ++ if (map->nsegs > (uint)(di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1)) { ++ goto outoftxd; ++ } ++ ++ nsegs = map->nsegs; ++ } else { ++ nsegs = 1; ++ } ++ ++ for (j = 1; j <= nsegs; j++) { ++ flags = 0; ++ if (p == p0 && j == 1) { ++ flags |= CTRL_SOF; ++ } ++ ++ /* With a DMA segment list, Descriptor table is filled ++ * using the segment list instead of looping over ++ * buffers in multi-chain DMA. Therefore, EOF for SGLIST is when ++ * end of segment list is reached. ++ */ ++ if ((!DMASGLIST_ENAB && next == NULL) || ++ (DMASGLIST_ENAB && j == nsegs)) { ++ flags |= (CTRL_IOC | CTRL_EOF); ++ } ++ if (txout == (di->ntxd - 1)) { ++ flags |= CTRL_EOT; ++ } ++ ++ if (DMASGLIST_ENAB) { ++ len = map->segs[j - 1].length; ++ pa = map->segs[j - 1].addr; ++ } ++ ASSERT(PHYSADDRHI(pa) == 0); ++ ++ dma32_dd_upd(di, di->txd32, pa, txout, &flags, len); ++ ASSERT(di->txp[txout] == NULL); ++ ++ txout = NEXTTXD(txout); ++ } ++ ++ /* See above. No need to loop over individual buffers */ ++ if (DMASGLIST_ENAB) { ++ break; ++ } ++ } ++ ++ /* if last txd eof not set, fix it */ ++ if (!(flags & CTRL_EOF)) { ++ W_SM(&di->txd32[PREVTXD(txout)].ctrl, BUS_SWAP32(flags | CTRL_IOC | CTRL_EOF)); ++ } ++ ++ /* save the packet */ ++ di->txp[PREVTXD(txout)] = p0; ++ ++ /* bump the tx descriptor index */ ++ di->txout = txout; ++ ++ /* kick the chip */ ++ if (commit) { ++ W_REG(di->osh, &di->d32txregs->ptr, I2B(txout, dma32dd_t)); ++ } ++ ++ /* tx flow control */ ++ di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ ++ return (0); ++ ++outoftxd: ++ DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name)); ++ PKTFREE(di->osh, p0, TRUE); ++ di->hnddma.txavail = 0; ++ di->hnddma.txnobuf++; ++ di->hnddma.txnodesc++; ++ return (-1); ++} ++ ++/* ++ * Reclaim next completed txd (txds if using chained buffers) in the range ++ * specified and return associated packet. ++ * If range is HNDDMA_RANGE_TRANSMITTED, reclaim descriptors that have be ++ * transmitted as noted by the hardware "CurrDescr" pointer. ++ * If range is HNDDMA_RANGE_TRANSFERED, reclaim descriptors that have be ++ * transfered by the DMA as noted by the hardware "ActiveDescr" pointer. ++ * If range is HNDDMA_RANGE_ALL, reclaim all txd(s) posted to the ring and ++ * return associated packet regardless of the value of hardware pointers. ++ */ ++static void * ++dma32_getnexttxp(dma_info_t *di, txd_range_t range) ++{ ++ uint16 start, end, i; ++ uint16 active_desc; ++ void *txp; ++ ++ DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, ++ (range == HNDDMA_RANGE_ALL) ? "all" : ++ ((range == HNDDMA_RANGE_TRANSMITTED) ? "transmitted" : "transfered"))); ++ ++ if (di->ntxd == 0) { ++ return (NULL); ++ } ++ ++ txp = NULL; ++ ++ start = di->txin; ++ if (range == HNDDMA_RANGE_ALL) { ++ end = di->txout; ++ } else { ++ dma32regs_t *dregs = di->d32txregs; ++ ++ if (di->txin == di->xs0cd) { ++ end = (uint16)B2I(R_REG(di->osh, &dregs->status) & XS_CD_MASK, dma32dd_t); ++ di->xs0cd = end; ++ } else { ++ end = di->xs0cd; ++ } ++ ++ if (range == HNDDMA_RANGE_TRANSFERED) { ++ active_desc = (uint16)((R_REG(di->osh, &dregs->status) & XS_AD_MASK) >> ++ XS_AD_SHIFT); ++ active_desc = (uint16)B2I(active_desc, dma32dd_t); ++ if (end != active_desc) { ++ end = PREVTXD(active_desc); ++ } ++ } ++ } ++ ++ if ((start == 0) && (end > di->txout)) { ++ goto bogus; ++ } ++ ++ for (i = start; i != end && !txp; i = NEXTTXD(i)) { ++ dmaaddr_t pa; ++ hnddma_seg_map_t *map = NULL; ++ uint size, j, nsegs; ++ ++ PHYSADDRLOSET(pa, (BUS_SWAP32(R_SM(&di->txd32[i].addr)) - di->dataoffsetlow)); ++ PHYSADDRHISET(pa, 0); ++ ++ if (DMASGLIST_ENAB) { ++ map = &di->txp_dmah[i]; ++ size = map->origsize; ++ nsegs = map->nsegs; ++ } else { ++ size = (BUS_SWAP32(R_SM(&di->txd32[i].ctrl)) & CTRL_BC_MASK); ++ nsegs = 1; ++ } ++ ++ for (j = nsegs; j > 0; j--) { ++ W_SM(&di->txd32[i].addr, 0xdeadbeef); ++ ++ txp = di->txp[i]; ++ di->txp[i] = NULL; ++ if (j > 1) { ++ i = NEXTTXD(i); ++ } ++ } ++ ++#ifndef CONFIG_BCM_IPROC_GMAC_ACP ++ DMA_UNMAP(di->osh, pa, size, DMA_TX, txp, map); ++#endif /* ! CONFIG_BCM_IPROC_GMAC_ACP */ ++ } ++ ++ di->txin = i; ++ ++ /* tx flow control */ ++ di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ ++ return (txp); ++ ++bogus: ++ DMA_NONE(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", ++ start, end, di->txout, forceall)); ++ return (NULL); ++} ++ ++static void * ++dma32_getnextrxp(dma_info_t *di, bool forceall) ++{ ++ uint16 i, curr; ++ void *rxp; ++ dmaaddr_t pa; ++ /* if forcing, dma engine must be disabled */ ++ ASSERT(!forceall || !dma32_rxenabled(di)); ++ ++ i = di->rxin; ++ ++ /* return if no packets posted */ ++ if (i == di->rxout) { ++ return (NULL); ++ } ++ ++ if (di->rxin == di->rs0cd) { ++ curr = (uint16)B2I(R_REG(di->osh, &di->d32rxregs->status) & RS_CD_MASK, dma32dd_t); ++ di->rs0cd = curr; ++ } else { ++ curr = di->rs0cd; ++ } ++ ++ /* ignore curr if forceall */ ++ if (!forceall && (i == curr)) { ++ return (NULL); ++ } ++ ++ /* get the packet pointer that corresponds to the rx descriptor */ ++ rxp = di->rxp[i]; ++ ASSERT(rxp); ++ di->rxp[i] = NULL; ++ ++ PHYSADDRLOSET(pa, (BUS_SWAP32(R_SM(&di->rxd32[i].addr)) - di->dataoffsetlow)); ++ PHYSADDRHISET(pa, 0); ++ ++ /* clear this packet from the descriptor ring */ ++#ifndef CONFIG_BCM_IPROC_GMAC_ACP ++ DMA_UNMAP(di->osh, pa, ++ di->rxbufsize, DMA_RX, rxp, &di->rxp_dmah[i]); ++#endif /* ! CONFIG_BCM_IPROC_GMAC_ACP */ ++ ++ W_SM(&di->rxd32[i].addr, 0xdeadbeef); ++ ++ di->rxin = NEXTRXD(i); ++ ++ return (rxp); ++} ++ ++/* ++ * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin). ++ */ ++static void ++dma32_txrotate(dma_info_t *di) ++{ ++ uint16 ad; ++ uint nactive; ++ uint rot; ++ uint16 old, new; ++ uint32 w; ++ uint16 first, last; ++ ++ ASSERT(dma32_txsuspendedidle(di)); ++ ++ nactive = _dma_txactive(di); ++ ad = B2I(((R_REG(di->osh, &di->d32txregs->status) & XS_AD_MASK) >> XS_AD_SHIFT), dma32dd_t); ++ rot = TXD(ad - di->txin); ++ ++ ASSERT(rot < di->ntxd); ++ ++ /* full-ring case is a lot harder - don't worry about this */ ++ if (rot >= (di->ntxd - nactive)) { ++ DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name)); ++ return; ++ } ++ ++ first = di->txin; ++ last = PREVTXD(di->txout); ++ ++ /* move entries starting at last and moving backwards to first */ ++ for (old = last; old != PREVTXD(first); old = PREVTXD(old)) { ++ new = TXD(old + rot); ++ ++ /* ++ * Move the tx dma descriptor. ++ * EOT is set only in the last entry in the ring. ++ */ ++ w = BUS_SWAP32(R_SM(&di->txd32[old].ctrl)) & ~CTRL_EOT; ++ if (new == (di->ntxd - 1)) { ++ w |= CTRL_EOT; ++ } ++ W_SM(&di->txd32[new].ctrl, BUS_SWAP32(w)); ++ W_SM(&di->txd32[new].addr, R_SM(&di->txd32[old].addr)); ++ ++ /* zap the old tx dma descriptor address field */ ++ W_SM(&di->txd32[old].addr, BUS_SWAP32(0xdeadbeef)); ++ ++ /* move the corresponding txp[] entry */ ++ ASSERT(di->txp[new] == NULL); ++ di->txp[new] = di->txp[old]; ++ ++ /* Move the segment map as well */ ++ if (DMASGLIST_ENAB) { ++ bcopy(&di->txp_dmah[old], &di->txp_dmah[new], sizeof(hnddma_seg_map_t)); ++ bzero(&di->txp_dmah[old], sizeof(hnddma_seg_map_t)); ++ } ++ ++ di->txp[old] = NULL; ++ } ++ ++ /* update txin and txout */ ++ di->txin = ad; ++ di->txout = TXD(di->txout + rot); ++ di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ ++ /* kick the chip */ ++ W_REG(di->osh, &di->d32txregs->ptr, I2B(di->txout, dma32dd_t)); ++} ++ ++/* 64-bit DMA functions */ ++ ++static void ++dma64_txinit(dma_info_t *di) ++{ ++ uint32 control; ++ ++ DMA_TRACE(("%s: dma_txinit\n", di->name)); ++ ++ if (di->ntxd == 0) { ++ return; ++ } ++ ++ di->txin = di->txout = di->xs0cd = di->xs0cd_snapshot = 0; ++ di->hnddma.txavail = di->ntxd - 1; ++ ++ /* clear tx descriptor ring */ ++ BZERO_SM((void *)(uintptr)di->txd64, (di->ntxd * sizeof(dma64dd_t))); ++ ++ /* These bits 20:18 (burstLen) of control register can be written but will take ++ * effect only if these bits are valid. So this will not affect previous versions ++ * of the DMA. They will continue to have those bits set to 0. ++ */ ++ control = R_REG(di->osh, &di->d64txregs->control); ++ control = (control & ~D64_XC_BL_MASK) | (di->txburstlen << D64_XC_BL_SHIFT); ++ control = (control & ~D64_XC_MR_MASK) | (di->txmultioutstdrd << D64_XC_MR_SHIFT); ++ control = (control & ~D64_XC_PC_MASK) | (di->txprefetchctl << D64_XC_PC_SHIFT); ++ control = (control & ~D64_XC_PT_MASK) | (di->txprefetchthresh << D64_XC_PT_SHIFT); ++ W_REG(di->osh, &di->d64txregs->control, control); ++ ++ control = D64_XC_XE; ++ /* DMA engine with out alignment requirement requires table to be inited ++ * before enabling the engine ++ */ ++ if (!di->aligndesc_4k) { ++ _dma_ddtable_init(di, DMA_TX, di->txdpa); ++ } ++ ++ if ((di->hnddma.dmactrlflags & DMA_CTRL_PEN) == 0) { ++ control |= D64_XC_PD; ++ } ++ OR_REG(di->osh, &di->d64txregs->control, control); ++ ++ /* DMA engine with alignment requirement requires table to be inited ++ * before enabling the engine ++ */ ++ if (di->aligndesc_4k) { ++ _dma_ddtable_init(di, DMA_TX, di->txdpa); ++ } ++} ++ ++static bool ++dma64_txenabled(dma_info_t *di) ++{ ++ uint32 xc; ++ ++ /* If the chip is dead, it is not enabled :-) */ ++ xc = R_REG(di->osh, &di->d64txregs->control); ++ return ((xc != 0xffffffff) && (xc & D64_XC_XE)); ++} ++ ++static void ++dma64_txsuspend(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_txsuspend\n", di->name)); ++ ++ if (di->ntxd == 0) { ++ return; ++ } ++ ++ OR_REG(di->osh, &di->d64txregs->control, D64_XC_SE); ++} ++ ++static void ++dma64_txresume(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_txresume\n", di->name)); ++ ++ if (di->ntxd == 0) { ++ return; ++ } ++ ++ AND_REG(di->osh, &di->d64txregs->control, ~D64_XC_SE); ++} ++ ++static bool ++dma64_txsuspended(dma_info_t *di) ++{ ++ return (di->ntxd == 0) || ++ ((R_REG(di->osh, &di->d64txregs->control) & D64_XC_SE) == D64_XC_SE); ++} ++ ++#ifdef WL_MULTIQUEUE ++static void ++dma64_txflush(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_txflush\n", di->name)); ++ ++ if (di->ntxd == 0) { ++ return; ++ } ++ ++ OR_REG(di->osh, &di->d64txregs->control, D64_XC_SE | D64_XC_FL); ++} ++ ++static void ++dma64_txflush_clear(dma_info_t *di) ++{ ++ uint32 status; ++ ++ DMA_TRACE(("%s: dma_txflush_clear\n", di->name)); ++ ++ if (di->ntxd == 0) { ++ return; ++ } ++ ++ SPINWAIT(((status = (R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK)) != ++ D64_XS0_XS_DISABLED) && ++ (status != D64_XS0_XS_IDLE) && ++ (status != D64_XS0_XS_STOPPED), ++ 10000); ++ AND_REG(di->osh, &di->d64txregs->control, ~D64_XC_FL); ++} ++#endif /* WL_MULTIQUEUE */ ++ ++static void BCMFASTPATH ++dma64_txreclaim(dma_info_t *di, txd_range_t range) ++{ ++ void *p; ++ ++ DMA_TRACE(("%s: dma_txreclaim %s\n", di->name, ++ (range == HNDDMA_RANGE_ALL) ? "all" : ++ ((range == HNDDMA_RANGE_TRANSMITTED) ? "transmitted" : "transfered"))); ++ ++ if (di->txin == di->txout) { ++ return; ++ } ++ ++ while ((p = dma64_getnexttxp(di, range))) { ++ /* For unframed data, we don't have any packets to free */ ++ if (!(di->hnddma.dmactrlflags & DMA_CTRL_UNFRAMED)) { ++ PKTFREE(di->osh, p, TRUE); ++ } ++ } ++} ++ ++static bool ++dma64_txstopped(dma_info_t *di) ++{ ++ return ((R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_STOPPED); ++} ++ ++static bool ++dma64_rxstopped(dma_info_t *di) ++{ ++ return ((R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_RS_MASK) == D64_RS0_RS_STOPPED); ++} ++ ++static bool ++dma64_alloc(dma_info_t *di, uint direction) ++{ ++ uint32 size; ++ uint ddlen; ++ void *va; ++ uint alloced = 0; ++ uint32 align; ++ uint16 align_bits; ++ ++ ddlen = sizeof(dma64dd_t); ++ ++ size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen); ++ align_bits = di->dmadesc_align; ++ align = (1 << align_bits); ++ ++ if (direction == DMA_TX) { ++ if ((va = dma_ringalloc(di->osh, ++ (di->d64_xs0_cd_mask == 0x1fff) ? D64RINGBOUNDARY : D64RINGBOUNDARY_LARGE, ++ size, &align_bits, &alloced, ++ &di->txdpaorig, &di->tx_dmah)) == NULL) { ++ DMA_ERROR(("%s: dma64_alloc: DMA_ALLOC_CONSISTENT(ntxd) failed\n", ++ di->name)); ++ return FALSE; ++ } ++ align = (1 << align_bits); ++ ++ /* adjust the pa by rounding up to the alignment */ ++ PHYSADDRLOSET(di->txdpa, ROUNDUP(PHYSADDRLO(di->txdpaorig), align)); ++ PHYSADDRHISET(di->txdpa, PHYSADDRHI(di->txdpaorig)); ++ ++ /* Make sure that alignment didn't overflow */ ++ ASSERT(PHYSADDRLO(di->txdpa) >= PHYSADDRLO(di->txdpaorig)); ++ ++ /* find the alignment offset that was used */ ++ di->txdalign = (uint)(PHYSADDRLO(di->txdpa) - PHYSADDRLO(di->txdpaorig)); ++ ++ /* adjust the va by the same offset */ ++ di->txd64 = (dma64dd_t *)((uintptr)va + di->txdalign); ++ ++ /* printk("%s di->txd64(0x%x-0x%x) \n", __FUNCTION__, PHYSADDRHI(di->txd64), PHYSADDRLO(di->txd64)); */ ++ /* printk("%s di->txdpa(0x%x-0x%x) \n", __FUNCTION__, PHYSADDRHI(di->txdpa), PHYSADDRLO(di->txdpa)); */ ++ di->txdalloc = alloced; ++ ASSERT(ISALIGNED(PHYSADDRLO(di->txdpa), align)); ++ } else { ++ if ((va = dma_ringalloc(di->osh, ++ (di->d64_rs0_cd_mask == 0x1fff) ? D64RINGBOUNDARY : D64RINGBOUNDARY_LARGE, ++ size, &align_bits, &alloced, ++ &di->rxdpaorig, &di->rx_dmah)) == NULL) { ++ DMA_ERROR(("%s: dma64_alloc: DMA_ALLOC_CONSISTENT(nrxd) failed\n", ++ di->name)); ++ return FALSE; ++ } ++ align = (1 << align_bits); ++ ++ /* adjust the pa by rounding up to the alignment */ ++ PHYSADDRLOSET(di->rxdpa, ROUNDUP(PHYSADDRLO(di->rxdpaorig), align)); ++ PHYSADDRHISET(di->rxdpa, PHYSADDRHI(di->rxdpaorig)); ++ ++ /* Make sure that alignment didn't overflow */ ++ ASSERT(PHYSADDRLO(di->rxdpa) >= PHYSADDRLO(di->rxdpaorig)); ++ ++ /* find the alignment offset that was used */ ++ di->rxdalign = (uint)(PHYSADDRLO(di->rxdpa) - PHYSADDRLO(di->rxdpaorig)); ++ ++ /* adjust the va by the same offset */ ++ di->rxd64 = (dma64dd_t *)((uintptr)va + di->rxdalign); ++ ++ /* printk("%s di->rxd64(0x%x-0x%x) \n", __FUNCTION__, PHYSADDRHI(di->rxd64), PHYSADDRLO(di->rxd64)); */ ++ /* printk("%s di->rxdpa(0x%x-0x%x) \n", __FUNCTION__, PHYSADDRHI(di->rxdpa), PHYSADDRLO(di->rxdpa)); */ ++ di->rxdalloc = alloced; ++ ASSERT(ISALIGNED(PHYSADDRLO(di->rxdpa), align)); ++ } ++ ++ return TRUE; ++} ++ ++static bool ++dma64_txreset(dma_info_t *di) ++{ ++ uint32 status; ++ ++ if (di->ntxd == 0) { ++ return TRUE; ++ } ++ ++ /* suspend tx DMA first */ ++ W_REG(di->osh, &di->d64txregs->control, D64_XC_SE); ++ ++ SPINWAIT(((status = (R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK)) != ++ D64_XS0_XS_DISABLED) && ++ (status != D64_XS0_XS_IDLE) && ++ (status != D64_XS0_XS_STOPPED), ++ 10000); ++ ++ W_REG(di->osh, &di->d64txregs->control, 0); ++ ++ SPINWAIT(((status = (R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK)) != ++ D64_XS0_XS_DISABLED), ++ 10000); ++ ++ /* We should be disabled at this point */ ++ if (status != D64_XS0_XS_DISABLED) { ++ DMA_ERROR(("%s: status != D64_XS0_XS_DISABLED 0x%x\n", __FUNCTION__, status)); ++ ASSERT(status == D64_XS0_XS_DISABLED); ++ OSL_DELAY(300); ++ } ++ ++ return (status == D64_XS0_XS_DISABLED); ++} ++ ++static bool ++dma64_rxidle(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_rxidle\n", di->name)); ++ ++ if (di->nrxd == 0) { ++ return TRUE; ++ } ++ ++ return ((R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_CD_MASK) == ++ (R_REG(di->osh, &di->d64rxregs->ptr) & D64_RS0_CD_MASK)); ++} ++ ++static bool ++dma64_rxreset(dma_info_t *di) ++{ ++ uint32 status; ++ ++ if (di->nrxd == 0) { ++ return TRUE; ++ } ++ ++ W_REG(di->osh, &di->d64rxregs->control, 0); ++ ++ SPINWAIT(((status = (R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_RS_MASK)) != ++ D64_RS0_RS_DISABLED), 10000); ++ ++ return (status == D64_RS0_RS_DISABLED); ++} ++ ++static bool ++dma64_rxenabled(dma_info_t *di) ++{ ++ uint32 rc; ++ ++ rc = R_REG(di->osh, &di->d64rxregs->control); ++ return ((rc != 0xffffffff) && (rc & D64_RC_RE)); ++} ++ ++static bool ++dma64_txsuspendedidle(dma_info_t *di) ++{ ++ ++ if (di->ntxd == 0) { ++ return TRUE; ++ } ++ ++ if (!(R_REG(di->osh, &di->d64txregs->control) & D64_XC_SE)) { ++ return 0; ++ } ++ ++ if ((R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_IDLE) { ++ return 1; ++ } ++ ++ return 0; ++} ++ ++/* Useful when sending unframed data. This allows us to get a progress report from the DMA. ++ * We return a pointer to the beginning of the data buffer of the current descriptor. ++ * If DMA is idle, we return NULL. ++ */ ++static void* ++dma64_getpos(dma_info_t *di, bool direction) ++{ ++ void *va; ++ bool idle; ++ uint16 cur_idx; ++ ++ if (direction == DMA_TX) { ++ cur_idx = B2I(((R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_CD_MASK) - ++ di->xmtptrbase) & D64_XS0_CD_MASK, dma64dd_t); ++ idle = !NTXDACTIVE(di->txin, di->txout); ++ va = di->txp[cur_idx]; ++ } else { ++ cur_idx = B2I(((R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_CD_MASK) - ++ di->rcvptrbase) & D64_RS0_CD_MASK, dma64dd_t); ++ idle = !NRXDACTIVE(di->rxin, di->rxout); ++ va = di->rxp[cur_idx]; ++ } ++ ++ /* If DMA is IDLE, return NULL */ ++ if (idle) { ++ DMA_TRACE(("%s: DMA idle, return NULL\n", __FUNCTION__)); ++ va = NULL; ++ } ++ ++ return va; ++} ++ ++/* TX of unframed data ++ * ++ * Adds a DMA ring descriptor for the data pointed to by "buf". ++ * This is for DMA of a buffer of data and is unlike other hnddma TX functions ++ * that take a pointer to a "packet" ++ * Each call to this is results in a single descriptor being added for "len" bytes of ++ * data starting at "buf", it doesn't handle chained buffers. ++ */ ++static int ++dma64_txunframed(dma_info_t *di, void *buf, uint len, bool commit) ++{ ++ uint16 txout; ++ uint32 flags = 0; ++ dmaaddr_t pa; /* phys addr */ ++ ++ txout = di->txout; ++ ++ /* return nonzero if out of tx descriptors */ ++ if (NEXTTXD(txout) == di->txin) { ++ goto outoftxd; ++ } ++ ++ if (len == 0) { ++ return 0; ++ } ++ ++#if defined(CONFIG_BCM_IPROC_GMAC_ACP) && !defined(BCMDMASGLISTOSL) ++ pa = virt_to_phys(buf); ++#else ++ pa = DMA_MAP(di->osh, buf, len, DMA_TX, NULL, &di->txp_dmah[txout]); ++#endif /* defined(CONFIG_BCM_IPROC_GMAC_ACP) && !defined(BCMDMASGLISTOSL) */ ++ ++ flags = (D64_CTRL1_SOF | D64_CTRL1_IOC | D64_CTRL1_EOF); ++ ++ if (txout == (di->ntxd - 1)) { ++ flags |= D64_CTRL1_EOT; ++ } ++ ++ dma64_dd_upd(di, di->txd64, pa, txout, &flags, len); ++ ASSERT(di->txp[txout] == NULL); ++ ++ /* save the buffer pointer - used by dma_getpos */ ++ di->txp[txout] = buf; ++ ++ txout = NEXTTXD(txout); ++ /* bump the tx descriptor index */ ++ di->txout = txout; ++ ++ /* kick the chip */ ++ if (commit) { ++ W_REG(di->osh, &di->d64txregs->ptr, di->xmtptrbase + I2B(txout, dma64dd_t)); ++ } ++ ++ /* tx flow control */ ++ di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ ++ return (0); ++ ++outoftxd: ++ DMA_ERROR(("%s: %s: out of txds !!!\n", di->name, __FUNCTION__)); ++ di->hnddma.txavail = 0; ++ di->hnddma.txnobuf++; ++ return (-1); ++} ++ ++/* RX of unframed data ++ * ++ * Adds a DMA ring descriptor for the data pointed to by "buf". ++ * This is for DMA of a buffer of data and is unlike other hnddma TX functions ++ * that take a pointer to a "packet" ++ * Each call to this is results in a single descriptor being added for "len" bytes of ++ * data starting at "buf", it doesn't handle chained buffers. ++ */ ++static int ++dma64_rxunframed(dma_info_t *di, void *buf, uint len, bool commit) ++{ ++ uint16 rxout; ++ uint32 flags = 0; ++ dmaaddr_t pa; /* phys addr */ ++ ++ rxout = di->rxout; ++ ++ /* return nonzero if out of rx descriptors */ ++ if (NEXTRXD(rxout) == di->rxin) { ++ goto outofrxd; ++ } ++ ++ if (len == 0) { ++ return 0; ++ } ++ ++#if defined(CONFIG_BCM_IPROC_GMAC_ACP) && !defined(BCMDMASGLISTOSL) ++ pa = virt_to_phys(buf); ++#else ++ pa = DMA_MAP(di->osh, buf, len, DMA_RX, NULL, &di->rxp_dmah[rxout]); ++#endif /* defined(CONFIG_BCM_IPROC_GMAC_ACP) && !defined(BCMDMASGLISTOSL) */ ++ ++ flags = (D64_CTRL1_SOF | D64_CTRL1_IOC | D64_CTRL1_EOF); ++ ++ if (rxout == (di->nrxd - 1)) { ++ flags |= D64_CTRL1_EOT; ++ } ++ ++ dma64_dd_upd(di, di->rxd64, pa, rxout, &flags, len); ++ ASSERT(di->rxp[rxout] == NULL); ++ ++ /* save the buffer pointer - used by dma_getpos */ ++ di->rxp[rxout] = buf; ++ ++ rxout = NEXTRXD(rxout); ++ /* bump the tx descriptor index */ ++ di->rxout = rxout; ++ ++ /* kick the chip */ ++ if (commit) { ++ W_REG(di->osh, &di->d64rxregs->ptr, di->rcvptrbase + I2B(rxout, dma64dd_t)); ++ //DBG("%s (Control Reg)W_REG: 0x%x Value: 0x%x\n", __FUNCTION__, &di->d64rxregs->ptr, di->rcvptrbase + I2B(rxout, dma64dd_t)); ++ } ++ ++ /* tx flow control */ ++ //di->hnddma.rxavail = di->nrxd - NRXDACTIVE(di->rxin, di->rxout) - 1; ++ ++ return (0); ++ ++outofrxd: ++ DMA_ERROR(("%s: %s: out of rxds !!!\n", di->name, __FUNCTION__)); ++ //di->hnddma.rxavail = 0; ++ di->hnddma.rxnobuf++; ++ return (-1); ++} ++ ++/* !! tx entry routine ++ * WARNING: call must check the return value for error. ++ * the error(toss frames) could be fatal and cause many subsequent hard to debug problems ++ */ ++static int BCMFASTPATH ++dma64_txfast(dma_info_t *di, void *p0, bool commit) ++{ ++ void *p, *next; ++ uchar *data; ++ uint len; ++ uint16 txout; ++ uint32 flags = 0; ++ dmaaddr_t pa; ++ bool war; ++ ++ DMA_TRACE(("%s: dma_txfast\n", di->name)); ++ ++ txout = di->txout; ++ war = (di->hnddma.dmactrlflags & DMA_CTRL_DMA_AVOIDANCE_WAR) ? TRUE : FALSE; ++ ++ /* ++ * Walk the chain of packet buffers ++ * allocating and initializing transmit descriptor entries. ++ */ ++ for (p = p0; p; p = next) { ++ uint nsegs, j, segsadd; ++ hnddma_seg_map_t *map = NULL; ++ ++ data = PKTDATA(di->osh, p); ++ len = PKTLEN(di->osh, p); ++#ifdef BCM_DMAPAD ++ len += PKTDMAPAD(di->osh, p); ++#endif /* BCM_DMAPAD */ ++ next = PKTNEXT(di->osh, p); ++ ++#ifdef CONFIG_BCM_IPROC_GMAC_PREFETCH ++ prefetch_range(next, SKB_PREFETCH_LEN); ++#endif ++ ++ /* return nonzero if out of tx descriptors */ ++ if (NEXTTXD(txout) == di->txin) { ++ goto outoftxd; ++ } ++ ++ if (len == 0) { ++ continue; ++ } ++ ++ /* get physical address of buffer start */ ++ if (DMASGLIST_ENAB) { ++ bzero(&di->txp_dmah[txout], sizeof(hnddma_seg_map_t)); ++ } ++ ++#if defined(CONFIG_BCM_IPROC_GMAC_ACP) && !defined(BCMDMASGLISTOSL) ++ pa = virt_to_phys(data); ++#else ++ pa = DMA_MAP(di->osh, data, len, DMA_TX, p, &di->txp_dmah[txout]); ++#endif /* defined(CONFIG_BCM_IPROC_GMAC_ACP) && !defined(BCMDMASGLISTOSL) */ ++ ++ ++ if (DMASGLIST_ENAB) { ++ map = &di->txp_dmah[txout]; ++ ++ /* See if all the segments can be accounted for */ ++ if (map->nsegs > (uint)(di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1)) { ++ goto outoftxd; ++ } ++ ++ nsegs = map->nsegs; ++ } else { ++ nsegs = 1; ++ } ++ ++ segsadd = 0; ++ for (j = 1; j <= nsegs; j++) { ++ flags = 0; ++ if (p == p0 && j == 1) { ++ flags |= D64_CTRL1_SOF; ++ } ++ ++ /* With a DMA segment list, Descriptor table is filled ++ * using the segment list instead of looping over ++ * buffers in multi-chain DMA. Therefore, EOF for SGLIST is when ++ * end of segment list is reached. ++ */ ++ if ((!DMASGLIST_ENAB && next == NULL) || ++ (DMASGLIST_ENAB && j == nsegs)) { ++ flags |= (D64_CTRL1_IOC | D64_CTRL1_EOF); ++ } ++ if (txout == (di->ntxd - 1)) { ++ flags |= D64_CTRL1_EOT; ++ } ++ ++ if (DMASGLIST_ENAB) { ++ len = map->segs[j - 1].length; ++ pa = map->segs[j - 1].addr; ++ if (len > 128 && war) { ++ uint remain, new_len, align64; ++ /* check for 64B aligned of pa */ ++ align64 = (uint)(PHYSADDRLO(pa) & 0x3f); ++ align64 = (64 - align64) & 0x3f; ++ new_len = len - align64; ++ remain = new_len % 128; ++ if (remain > 0 && remain <= 4) { ++ uint32 buf_addr_lo; ++ uint32 tmp_flags = ++ flags & (~(D64_CTRL1_EOF | D64_CTRL1_IOC)); ++ flags &= ~(D64_CTRL1_SOF | D64_CTRL1_EOT); ++ remain += 64; ++ dma64_dd_upd(di, di->txd64, pa, txout, ++ &tmp_flags, len-remain); ++ ASSERT(di->txp[txout] == NULL); ++ txout = NEXTTXD(txout); ++ /* return nonzero if out of tx descriptors */ ++ if (txout == di->txin) { ++ DMA_ERROR(("%s: dma_txfast: Out-of-DMA" ++ " descriptors (txin %d txout %d" ++ " nsegs %d)\n", __FUNCTION__, ++ di->txin, di->txout, nsegs)); ++ goto outoftxd; ++ } ++ if (txout == (di->ntxd - 1)) { ++ flags |= D64_CTRL1_EOT; ++ } ++ buf_addr_lo = PHYSADDRLO(pa); ++ PHYSADDRLOSET(pa, (PHYSADDRLO(pa) + (len-remain))); ++ if (PHYSADDRLO(pa) < buf_addr_lo) { ++ PHYSADDRHISET(pa, (PHYSADDRHI(pa) + 1)); ++ } ++ len = remain; ++ segsadd++; ++ di->dma_avoidance_cnt++; ++ } ++ } ++ } ++ dma64_dd_upd(di, di->txd64, pa, txout, &flags, len); ++ ASSERT(di->txp[txout] == NULL); ++ ++ txout = NEXTTXD(txout); ++ /* return nonzero if out of tx descriptors */ ++ if (txout == di->txin) { ++ DMA_ERROR(("%s: dma_txfast: Out-of-DMA descriptors" ++ " (txin %d txout %d nsegs %d)\n", __FUNCTION__, ++ di->txin, di->txout, nsegs)); ++ goto outoftxd; ++ } ++ } ++ if (segsadd && DMASGLIST_ENAB) { ++ map->nsegs += segsadd; ++ } ++ ++ /* See above. No need to loop over individual buffers */ ++ if (DMASGLIST_ENAB) { ++ break; ++ } ++ } ++ ++ /* if last txd eof not set, fix it */ ++ if (!(flags & D64_CTRL1_EOF)) { ++ W_SM(&di->txd64[PREVTXD(txout)].ctrl1, ++ BUS_SWAP32(flags | D64_CTRL1_IOC | D64_CTRL1_EOF)); ++ } ++ ++ /* save the packet */ ++ di->txp[PREVTXD(txout)] = p0; ++ ++ /* bump the tx descriptor index */ ++ di->txout = txout; ++ ++ /* Spin lock to prevent TX discriptor protocol errors when using SG lists */ ++ spin_lock(&di->des_lock); ++ spin_unlock(&di->des_lock); ++ ++ /* kick the chip */ ++ if (commit) { ++ W_REG(di->osh, &di->d64txregs->ptr, di->xmtptrbase + I2B(txout, dma64dd_t)); ++ } ++ ++ /* tx flow control */ ++ di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ ++ return (0); ++ ++outoftxd: ++ DMA_ERROR(("%s: dma_txfast: out of txds !!!\n", di->name)); ++ PKTFREE(di->osh, p0, TRUE); ++ di->hnddma.txavail = 0; ++ di->hnddma.txnobuf++; ++ return (-1); ++} ++ ++/* ++ * Reclaim next completed txd (txds if using chained buffers) in the range ++ * specified and return associated packet. ++ * If range is HNDDMA_RANGE_TRANSMITTED, reclaim descriptors that have be ++ * transmitted as noted by the hardware "CurrDescr" pointer. ++ * If range is HNDDMA_RANGE_TRANSFERED, reclaim descriptors that have be ++ * transfered by the DMA as noted by the hardware "ActiveDescr" pointer. ++ * If range is HNDDMA_RANGE_ALL, reclaim all txd(s) posted to the ring and ++ * return associated packet regardless of the value of hardware pointers. ++ */ ++static void * BCMFASTPATH ++dma64_getnexttxp(dma_info_t *di, txd_range_t range) ++{ ++ uint16 start, end, i; ++ uint16 active_desc; ++ void *txp; ++ ++ DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, ++ (range == HNDDMA_RANGE_ALL) ? "all" : ++ ((range == HNDDMA_RANGE_TRANSMITTED) ? "transmitted" : "transfered"))); ++ ++ if (di->ntxd == 0) { ++ return (NULL); ++ } ++ ++ txp = NULL; ++ ++ start = di->txin; ++ if (range == HNDDMA_RANGE_ALL) { ++ end = di->txout; ++ } else { ++ dma64regs_t *dregs = di->d64txregs; ++ ++ if (di->txin == di->xs0cd) { ++ end = (uint16)(B2I(((R_REG(di->osh, &dregs->status0) & D64_XS0_CD_MASK) - ++ di->xmtptrbase) & D64_XS0_CD_MASK, dma64dd_t)); ++ di->xs0cd = end; ++ } else { ++ end = di->xs0cd; ++ } ++ ++ if (range == HNDDMA_RANGE_TRANSFERED) { ++ active_desc = (uint16)(R_REG(di->osh, &dregs->status1) & D64_XS1_AD_MASK); ++ active_desc = (active_desc - di->xmtptrbase) & D64_XS0_CD_MASK; ++ active_desc = B2I(active_desc, dma64dd_t); ++ if (end != active_desc) { ++ end = PREVTXD(active_desc); ++ } ++ } ++ } ++ ++ if ((start == 0) && (end > di->txout)) { ++ goto bogus; ++ } ++ ++ for (i = start; i != end && !txp; i = NEXTTXD(i)) { ++ dmaaddr_t pa; ++ hnddma_seg_map_t *map = NULL; ++ uint size, j, nsegs; ++ ++#ifdef CONFIG_BCM_IPROC_GMAC_PREFETCH ++ prefetch_range(di->txp[NEXTTXD(i)], SKB_PREFETCH_LEN); ++#endif ++ ++ PHYSADDRLOSET(pa, (BUS_SWAP32(R_SM(&di->txd64[i].addrlow)) - di->dataoffsetlow)); ++ PHYSADDRHISET(pa, (BUS_SWAP32(R_SM(&di->txd64[i].addrhigh)) - di->dataoffsethigh)); ++ ++ if (DMASGLIST_ENAB) { ++ map = &di->txp_dmah[i]; ++ size = map->origsize; ++ nsegs = map->nsegs; ++ if (nsegs > (uint)NTXDACTIVE(i, end)) { ++ di->xs0cd = i; ++ break; ++ } ++ } else { ++ size = (BUS_SWAP32(R_SM(&di->txd64[i].ctrl2)) & D64_CTRL2_BC_MASK); ++ nsegs = 1; ++ } ++ ++ for (j = nsegs; j > 0; j--) { ++ W_SM(&di->txd64[i].addrlow, 0xdeadbeef); ++ W_SM(&di->txd64[i].addrhigh, 0xdeadbeef); ++ ++ txp = di->txp[i]; ++ di->txp[i] = NULL; ++ if (j > 1) { ++ i = NEXTTXD(i); ++ } ++ } ++#ifndef CONFIG_BCM_IPROC_GMAC_ACP ++ DMA_UNMAP(di->osh, pa, size, DMA_TX, txp, map); ++#endif /* ! CONFIG_BCM_IPROC_GMAC_ACP */ ++ } ++ ++ di->txin = i; ++ ++ /* tx flow control */ ++ di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ ++ return (txp); ++ ++bogus: ++ DMA_NONE(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", ++ start, end, di->txout, forceall)); ++ return (NULL); ++} ++ ++static void * BCMFASTPATH ++dma64_getnextrxp(dma_info_t *di, bool forceall) ++{ ++ uint16 i, curr; ++ void *rxp; ++ dmaaddr_t pa; ++ ++ /* if forcing, dma engine must be disabled */ ++ ASSERT(!forceall || !dma64_rxenabled(di)); ++ ++ i = di->rxin; ++ ++ /* return if no packets posted */ ++ if (i == di->rxout) { ++ return (NULL); ++ } ++ ++#ifdef CONFIG_BCM_IPROC_GMAC_PREFETCH ++ prefetch_range(di->rxp[NEXTRXD(i)], SKB_PREFETCH_LEN); ++#endif ++ ++ if (di->rxin == di->rs0cd) { ++ curr = (uint16)B2I(((R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_CD_MASK) - ++ di->rcvptrbase) & D64_RS0_CD_MASK, dma64dd_t); ++ di->rs0cd = curr; ++ } else { ++ curr = di->rs0cd; ++ } ++ ++ /* ignore curr if forceall */ ++ if (!forceall && (i == curr)) { ++ return (NULL); ++ } ++ ++ /* get the packet pointer that corresponds to the rx descriptor */ ++ rxp = di->rxp[i]; ++ ASSERT(rxp); ++ di->rxp[i] = NULL; ++ ++ PHYSADDRLOSET(pa, (BUS_SWAP32(R_SM(&di->rxd64[i].addrlow)) - di->dataoffsetlow)); ++ PHYSADDRHISET(pa, (BUS_SWAP32(R_SM(&di->rxd64[i].addrhigh)) - di->dataoffsethigh)); ++ ++ /* clear this packet from the descriptor ring */ ++#ifndef CONFIG_BCM_IPROC_GMAC_ACP ++ DMA_UNMAP(di->osh, pa, ++ di->rxbufsize, DMA_RX, rxp, &di->rxp_dmah[i]); ++#endif /* ! CONFIG_BCM_IPROC_GMAC_ACP */ ++ ++ W_SM(&di->rxd64[i].addrlow, 0xdeadbeef); ++ W_SM(&di->rxd64[i].addrhigh, 0xdeadbeef); ++ ++ di->rxin = NEXTRXD(i); ++ ++ return (rxp); ++} ++ ++static bool ++_dma64_addrext(osl_t *osh, dma64regs_t *dma64regs) ++{ ++ uint32 w; ++ OR_REG(osh, &dma64regs->control, D64_XC_AE); ++ w = R_REG(osh, &dma64regs->control); ++ AND_REG(osh, &dma64regs->control, ~D64_XC_AE); ++ return ((w & D64_XC_AE) == D64_XC_AE); ++} ++ ++/* ++ * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin). ++ */ ++static void ++dma64_txrotate(dma_info_t *di) ++{ ++ uint16 ad; ++ uint nactive; ++ uint rot; ++ uint16 old, new; ++ uint32 w; ++ uint16 first, last; ++ ++ ASSERT(dma64_txsuspendedidle(di)); ++ ++ nactive = _dma_txactive(di); ++ ad = B2I((((R_REG(di->osh, &di->d64txregs->status1) & D64_XS1_AD_MASK) ++ - di->xmtptrbase) & D64_XS1_AD_MASK), dma64dd_t); ++ rot = TXD(ad - di->txin); ++ ++ ASSERT(rot < di->ntxd); ++ ++ /* full-ring case is a lot harder - don't worry about this */ ++ if (rot >= (di->ntxd - nactive)) { ++ DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name)); ++ return; ++ } ++ ++ first = di->txin; ++ last = PREVTXD(di->txout); ++ ++ /* move entries starting at last and moving backwards to first */ ++ for (old = last; old != PREVTXD(first); old = PREVTXD(old)) { ++ new = TXD(old + rot); ++ ++ /* ++ * Move the tx dma descriptor. ++ * EOT is set only in the last entry in the ring. ++ */ ++ w = BUS_SWAP32(R_SM(&di->txd64[old].ctrl1)) & ~D64_CTRL1_EOT; ++ if (new == (di->ntxd - 1)) { ++ w |= D64_CTRL1_EOT; ++ } ++ W_SM(&di->txd64[new].ctrl1, BUS_SWAP32(w)); ++ ++ w = BUS_SWAP32(R_SM(&di->txd64[old].ctrl2)); ++ W_SM(&di->txd64[new].ctrl2, BUS_SWAP32(w)); ++ ++ W_SM(&di->txd64[new].addrlow, R_SM(&di->txd64[old].addrlow)); ++ W_SM(&di->txd64[new].addrhigh, R_SM(&di->txd64[old].addrhigh)); ++ ++ /* zap the old tx dma descriptor address field */ ++ W_SM(&di->txd64[old].addrlow, BUS_SWAP32(0xdeadbeef)); ++ W_SM(&di->txd64[old].addrhigh, BUS_SWAP32(0xdeadbeef)); ++ ++ /* move the corresponding txp[] entry */ ++ ASSERT(di->txp[new] == NULL); ++ di->txp[new] = di->txp[old]; ++ ++ /* Move the map */ ++ if (DMASGLIST_ENAB) { ++ bcopy(&di->txp_dmah[old], &di->txp_dmah[new], sizeof(hnddma_seg_map_t)); ++ bzero(&di->txp_dmah[old], sizeof(hnddma_seg_map_t)); ++ } ++ ++ di->txp[old] = NULL; ++ } ++ ++ /* update txin and txout */ ++ di->txin = ad; ++ di->txout = TXD(di->txout + rot); ++ di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ ++ /* kick the chip */ ++ W_REG(di->osh, &di->d64txregs->ptr, di->xmtptrbase + I2B(di->txout, dma64dd_t)); ++} ++ ++uint ++BCMATTACHFN(dma_addrwidth)(si_t *sih, void *dmaregs) ++{ ++ dma32regs_t *dma32regs; ++ osl_t *osh; ++ ++ osh = si_osh(sih); ++ ++ /* Perform 64-bit checks only if we want to advertise 64-bit (> 32bit) capability) */ ++ /* DMA engine is 64-bit capable */ ++ if ((si_core_sflags(sih, 0, 0) & SISF_DMA64) == SISF_DMA64) { ++ /* backplane are 64-bit capable */ ++ if (si_backplane64(sih)) { ++ /* If bus is System Backplane or PCIE then we can access 64-bits */ ++ if ((BUSTYPE(sih->bustype) == SI_BUS) || ++ ((BUSTYPE(sih->bustype) == PCI_BUS) && ++ ((sih->buscoretype == PCIE_CORE_ID) || ++ (sih->buscoretype == PCIE2_CORE_ID)))) { ++ return (DMADDRWIDTH_64); ++ } ++ } ++ ++ /* DMA64 is always 32-bit capable, AE is always TRUE */ ++ ASSERT(_dma64_addrext(osh, (dma64regs_t *)dmaregs)); ++ ++ return (DMADDRWIDTH_32); ++ } ++ ++ /* Start checking for 32-bit / 30-bit addressing */ ++ dma32regs = (dma32regs_t *)dmaregs; ++ ++ /* For System Backplane, PCIE bus or addrext feature, 32-bits ok */ ++ if ((BUSTYPE(sih->bustype) == SI_BUS) || ++ ((BUSTYPE(sih->bustype) == PCI_BUS) && ++ ((sih->buscoretype == PCIE_CORE_ID) || ++ (sih->buscoretype == PCIE2_CORE_ID))) || ++ (_dma32_addrext(osh, dma32regs))) { ++ return (DMADDRWIDTH_32); ++ } ++ ++ /* Fallthru */ ++ return (DMADDRWIDTH_30); ++} ++ ++static int ++_dma_pktpool_set(dma_info_t *di, pktpool_t *pool) ++{ ++ ASSERT(di); ++ ASSERT(di->pktpool == NULL); ++ di->pktpool = pool; ++ return 0; ++} ++ ++static bool ++_dma_rxtx_error(dma_info_t *di, bool istx) ++{ ++ uint32 status1 = 0; ++ uint16 curr; ++ ++ if (DMA64_ENAB(di) && DMA64_MODE(di)) { ++ if (istx) { ++ status1 = R_REG(di->osh, &di->d64txregs->status1); ++ ++ if ((status1 & D64_XS1_XE_MASK) != D64_XS1_XE_NOERR) { ++ return TRUE; ++ } else if (si_coreid(di->sih) == GMAC_CORE_ID && si_corerev(di->sih) >= 4) { ++ curr = (uint16)(B2I(((R_REG(di->osh, &di->d64txregs->status0) & ++ D64_XS0_CD_MASK) - di->xmtptrbase) & ++ D64_XS0_CD_MASK, dma64dd_t)); ++ ++ if (NTXDACTIVE(di->txin, di->txout) != 0 && ++ curr == di->xs0cd_snapshot) { ++ ++ /* suspicious */ ++ return TRUE; ++ } ++ di->xs0cd_snapshot = di->xs0cd = curr; ++ ++ return FALSE; ++ } else { ++ return FALSE; ++ } ++ } ++ else { ++ ++ status1 = R_REG(di->osh, &di->d64rxregs->status1); ++ ++ if ((status1 & D64_RS1_RE_MASK) != D64_RS1_RE_NOERR) { ++ return TRUE; ++ } else { ++ return FALSE; ++ } ++ } ++ } else if (DMA32_ENAB(di)) { ++ return FALSE; ++ } else { ++ ASSERT(0); ++ return FALSE; ++ } ++ ++} ++ ++void ++_dma_burstlen_set(dma_info_t *di, uint8 rxburstlen, uint8 txburstlen) ++{ ++ di->rxburstlen = rxburstlen; ++ di->txburstlen = txburstlen; ++} ++ ++void ++_dma_param_set(dma_info_t *di, uint16 paramid, uint16 paramval) ++{ ++ switch (paramid) { ++ case HNDDMA_PID_TX_MULTI_OUTSTD_RD: ++ di->txmultioutstdrd = (uint8)paramval; ++ break; ++ ++ case HNDDMA_PID_TX_PREFETCH_CTL: ++ di->txprefetchctl = (uint8)paramval; ++ break; ++ ++ case HNDDMA_PID_TX_PREFETCH_THRESH: ++ di->txprefetchthresh = (uint8)paramval; ++ break; ++ ++ case HNDDMA_PID_TX_BURSTLEN: ++ di->txburstlen = (uint8)paramval; ++ break; ++ ++ case HNDDMA_PID_RX_PREFETCH_CTL: ++ di->rxprefetchctl = (uint8)paramval; ++ break; ++ ++ case HNDDMA_PID_RX_PREFETCH_THRESH: ++ di->rxprefetchthresh = (uint8)paramval; ++ break; ++ ++ case HNDDMA_PID_RX_BURSTLEN: ++ di->rxburstlen = (uint8)paramval; ++ break; ++ ++ default: ++ break; ++ } ++} ++ ++static bool ++_dma_glom_enable(dma_info_t *di, uint32 val) ++{ ++ dma64regs_t *dregs = di->d64rxregs; ++ bool ret = TRUE; ++ if (val) { ++ OR_REG(di->osh, &dregs->control, D64_RC_GE); ++ if (!(R_REG(di->osh, &dregs->control) & D64_RC_GE)) ++ ret = FALSE; ++ } else { ++ AND_REG(di->osh, &dregs->control, ~D64_RC_GE); ++ } ++ return ret; ++} +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/hr2_erom.c b/drivers/net/ethernet/broadcom/gmac/src/shared/hr2_erom.c +--- a/drivers/net/ethernet/broadcom/gmac/src/shared/hr2_erom.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/shared/hr2_erom.c 2017-11-09 17:53:44.051300000 +0800 +@@ -0,0 +1,64 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Broadcom Home Networking Division 10/100 Mbit/s Ethernet ++ * Helix4 sudo EROM ++ * ++ */ ++#include ++ ++uint32 hr2_erom[] = { ++ //#define CC_CORE_ID 0x800 /* chipcommon core */ ++ 0x4bf80001, 0x2a004201, 0x18000005, 0x181200c5, ++ //#define NS_CCB_CORE_ID 0x50b /* ChipcommonB core */ ++ 0x4bf50b01, 0x01000201, 0x18001005, 0x18002005, 0x18003005, 0x18004005, 0x18005005, 0x18006005, 0x18007005, 0x18008005, 0x18009005, ++ //#define NS_DMA_CORE_ID 0x502 /* DMA core */ ++ 0x4bf50201, 0x01004211, 0x00000003, 0x1802c005, 0x181140c5, ++ //#define GMAC_CORE_ID 0x82d /* Gigabit MAC core */ ++ 0x4bf82d01, 0x04004211, 0x00000103, 0x18022005, 0x181100c5, ++ //#define NS_PCIEG2_CORE_ID 0x501 /* PCIE Gen 2 core */ ++ 0x4bf50101, 0x01084411, 0x00000503, 0x18012005, 0x08000135, 0x08000000, 0x181010c5, 0x1810a185, ++ 0x4bf50101, 0x01084411, 0x00000603, 0x18013005, 0x40000135, 0x08000000, 0x181020c5, 0x1810b185, ++ 0x4bf50101, 0x01084411, 0x00000703, 0x18014005, 0x48000135, 0x08000000, 0x181030c5, 0x1810c185, ++ //#define ARMCA9_CORE_ID 0x510 /* ARM Cortex A9 core (ihost) */ ++ 0x4bf51001, 0x01104611, 0x00000803, 0x1800b005, 0x1800c005, 0x19000135, 0x00020000, 0x19020235, 0x00003000, 0x181000c5, 0x18106185, 0x18107285, ++ //#define NS_USB20_CORE_ID 0x504 /* USB2.0 core */ ++ 0x4bf50401, 0x01004211, 0x00000903, 0x18021005, 0x18022005, 0x181150c5, ++ //#define NS_USB30_CORE_ID 0x505 /* USB3.0 core */ ++ 0x4bf50501, 0x01004211, 0x00000a03, 0x18023005, 0x181050c5, ++ //#define NS_SDIO3_CORE_ID 0x503 /* SDIO3 core */ ++ 0x4bf50301, 0x01004211, 0x00000b03, 0x18020005, 0x181160c5, ++ //#define I2S_CORE_ID 0x834 /* I2S core */ ++ 0x4bf83401, 0x03004211, 0x00000c03, 0x1802a005, 0x181170c5, ++ //#define NS_A9JTAG_CORE_ID 0x506 /* ARM Cortex A9 JTAG core */ ++ 0x4bf50601, 0x01084211, 0x00000d03, 0x18210035, 0x00010000, 0x181180c5, 0x1811c085, ++ //#define NS_DDR23_CORE_ID 0x507 /* Denali DDR2/DDR3 memory controller */ ++ 0x4bf50701, 0x01100601, 0x18010005, 0x00000135, 0x08000000, 0x80000135, 0x30000000, 0xb0000235, 0x10000000, 0x18108185, 0x18109285, ++ //#define NS_ROM_CORE_ID 0x508 /* ROM core */ ++ 0x4bf50801, 0x01080201, 0xfffd0035, 0x00030000, 0x1810d085, ++ //#define NS_NAND_CORE_ID 0x509 /* NAND flash controller core */ ++ 0x4bf50901, 0x01080401, 0x18028005, 0x1c000135, 0x02000000, 0x1811a185, ++ //#define NS_QSPI_CORE_ID 0x50a /* SPI flash controller core */ ++ 0x4bf50a01, 0x01080401, 0x18029005, 0x1e000135, 0x02000000, 0x1811b185, ++ //#define EROM_CORE_ID 0x366 /* EROM core ID */ ++ 0x43b36601, 0x00000201, 0x18130005, ++ 0x43b13501, 0x00080201, 0x18000075, 0x00010000, 0x18121085, ++ 0x43b30101, 0x01000201, 0x1a000035, 0x00100000, ++ 0x43bfff01, 0x00280a01, 0x10000035, 0x08000000, 0x18011005, 0x18015035, 0x0000b000, 0x1802b105, 0x1802d135, 0x000d3000, 0x18104105, 0x1810e215, ++ 0x18119205, 0x1811d235, 0x00003000, 0x18122335, 0x0000e000, 0x18131305, 0x18137335, 0x000d9000, 0x18220335, 0x000de000, 0x19023335, ++ 0x00fdd000, 0x1a100335, 0x01f00000, 0x20000435, 0x20000000, 0x50000435, 0x30000000, 0xc0000435, 0x3ffd0000, 0x18132085, 0x18133185, ++ 0x18134285, 0x18135385, 0x18136485, ++ 0x0000000f ++}; +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/hr2_erom.h b/drivers/net/ethernet/broadcom/gmac/src/shared/hr2_erom.h +--- a/drivers/net/ethernet/broadcom/gmac/src/shared/hr2_erom.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/shared/hr2_erom.h 2017-11-09 17:53:44.052298000 +0800 +@@ -0,0 +1,26 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Broadcom Home Networking Division 10/100 Mbit/s Ethernet ++ * Helix4 sudo EROM ++ * ++ */ ++ ++#ifndef _hr2_erom_h_ ++#define _hr2_erom_h_ ++ ++extern uint32 hr2_erom[]; ++ ++#endif //_hr2_erom_h_ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/hr3_erom.c b/drivers/net/ethernet/broadcom/gmac/src/shared/hr3_erom.c +--- a/drivers/net/ethernet/broadcom/gmac/src/shared/hr3_erom.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/shared/hr3_erom.c 2017-11-09 17:53:44.053293000 +0800 +@@ -0,0 +1,28 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Broadcom Home Networking Division 10/100 Mbit/s Ethernet ++ * Hurricane3 sudo EROM ++ * ++ */ ++#include ++ ++uint32 hr3_erom[] = { ++ //#define CC_CORE_ID 0x800 /* chipcommon core */ ++ 0x4bf80001, 0x2a004201, 0x18000005, 0x181200c5, ++ //#define GMAC_CORE_ID 0x82d /* Gigabit MAC core */ ++ 0x4bf82d01, 0x04004211, 0x00000103, 0x18042005, 0x181100c5, ++ 0x0000000f ++}; +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/hr3_erom.h b/drivers/net/ethernet/broadcom/gmac/src/shared/hr3_erom.h +--- a/drivers/net/ethernet/broadcom/gmac/src/shared/hr3_erom.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/shared/hr3_erom.h 2017-11-09 17:53:44.054288000 +0800 +@@ -0,0 +1,26 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Broadcom Home Networking Division 10/100 Mbit/s Ethernet ++ * Hurricane3 sudo EROM ++ * ++ */ ++ ++#ifndef _hr3_erom_h_ ++#define _hr3_erom_h_ ++ ++extern uint32 hr3_erom[]; ++ ++#endif /* _hr3_erom_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/hx4_erom.c b/drivers/net/ethernet/broadcom/gmac/src/shared/hx4_erom.c +--- a/drivers/net/ethernet/broadcom/gmac/src/shared/hx4_erom.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/shared/hx4_erom.c 2017-11-09 17:53:44.054324000 +0800 +@@ -0,0 +1,65 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Broadcom Home Networking Division 10/100 Mbit/s Ethernet ++ * Helix4 sudo EROM ++ * ++ */ ++#include ++ ++uint32 hx4_erom[] = { ++ //#define CC_CORE_ID 0x800 /* chipcommon core */ ++ 0x4bf80001, 0x2a004201, 0x18000005, 0x181200c5, ++ //#define NS_CCB_CORE_ID 0x50b /* ChipcommonB core */ ++ 0x4bf50b01, 0x01000201, 0x18001005, 0x18002005, 0x18003005, 0x18004005, 0x18005005, 0x18006005, 0x18007005, 0x18008005, 0x18009005, ++ //#define NS_DMA_CORE_ID 0x502 /* DMA core */ ++ 0x4bf50201, 0x01004211, 0x00000003, 0x1802c005, 0x181140c5, ++ //#define GMAC_CORE_ID 0x82d /* Gigabit MAC core */ ++ 0x4bf82d01, 0x04004211, 0x00000103, 0x18022005, 0x181100c5, ++ 0x4bf82d01, 0x04004211, 0x00000203, 0x18023005, 0x181110c5, ++ //#define NS_PCIEG2_CORE_ID 0x501 /* PCIE Gen 2 core */ ++ 0x4bf50101, 0x01084411, 0x00000503, 0x18012005, 0x08000135, 0x08000000, 0x181010c5, 0x1810a185, ++ 0x4bf50101, 0x01084411, 0x00000603, 0x18013005, 0x40000135, 0x08000000, 0x181020c5, 0x1810b185, ++ 0x4bf50101, 0x01084411, 0x00000703, 0x18014005, 0x48000135, 0x08000000, 0x181030c5, 0x1810c185, ++ //#define ARMCA9_CORE_ID 0x510 /* ARM Cortex A9 core (ihost) */ ++ 0x4bf51001, 0x01104611, 0x00000803, 0x1800b005, 0x1800c005, 0x19000135, 0x00020000, 0x19020235, 0x00003000, 0x181000c5, 0x18106185, 0x18107285, ++ //#define NS_USB20_CORE_ID 0x504 /* USB2.0 core */ ++ 0x4bf50401, 0x01004211, 0x00000903, 0x18021005, 0x18022005, 0x181150c5, ++ //#define NS_USB30_CORE_ID 0x505 /* USB3.0 core */ ++ 0x4bf50501, 0x01004211, 0x00000a03, 0x18023005, 0x181050c5, ++ //#define NS_SDIO3_CORE_ID 0x503 /* SDIO3 core */ ++ 0x4bf50301, 0x01004211, 0x00000b03, 0x18020005, 0x181160c5, ++ //#define I2S_CORE_ID 0x834 /* I2S core */ ++ 0x4bf83401, 0x03004211, 0x00000c03, 0x1802a005, 0x181170c5, ++ //#define NS_A9JTAG_CORE_ID 0x506 /* ARM Cortex A9 JTAG core */ ++ 0x4bf50601, 0x01084211, 0x00000d03, 0x18210035, 0x00010000, 0x181180c5, 0x1811c085, ++ //#define NS_DDR23_CORE_ID 0x507 /* Denali DDR2/DDR3 memory controller */ ++ 0x4bf50701, 0x01100601, 0x18010005, 0x00000135, 0x08000000, 0x80000135, 0x30000000, 0xb0000235, 0x10000000, 0x18108185, 0x18109285, ++ //#define NS_ROM_CORE_ID 0x508 /* ROM core */ ++ 0x4bf50801, 0x01080201, 0xfffd0035, 0x00030000, 0x1810d085, ++ //#define NS_NAND_CORE_ID 0x509 /* NAND flash controller core */ ++ 0x4bf50901, 0x01080401, 0x18028005, 0x1c000135, 0x02000000, 0x1811a185, ++ //#define NS_QSPI_CORE_ID 0x50a /* SPI flash controller core */ ++ 0x4bf50a01, 0x01080401, 0x18029005, 0x1e000135, 0x02000000, 0x1811b185, ++ //#define EROM_CORE_ID 0x366 /* EROM core ID */ ++ 0x43b36601, 0x00000201, 0x18130005, ++ 0x43b13501, 0x00080201, 0x18000075, 0x00010000, 0x18121085, ++ 0x43b30101, 0x01000201, 0x1a000035, 0x00100000, ++ 0x43bfff01, 0x00280a01, 0x10000035, 0x08000000, 0x18011005, 0x18015035, 0x0000b000, 0x1802b105, 0x1802d135, 0x000d3000, 0x18104105, 0x1810e215, ++ 0x18119205, 0x1811d235, 0x00003000, 0x18122335, 0x0000e000, 0x18131305, 0x18137335, 0x000d9000, 0x18220335, 0x000de000, 0x19023335, ++ 0x00fdd000, 0x1a100335, 0x01f00000, 0x20000435, 0x20000000, 0x50000435, 0x30000000, 0xc0000435, 0x3ffd0000, 0x18132085, 0x18133185, ++ 0x18134285, 0x18135385, 0x18136485, ++ 0x0000000f ++}; +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/hx4_erom.h b/drivers/net/ethernet/broadcom/gmac/src/shared/hx4_erom.h +--- a/drivers/net/ethernet/broadcom/gmac/src/shared/hx4_erom.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/shared/hx4_erom.h 2017-11-09 17:53:44.055299000 +0800 +@@ -0,0 +1,26 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Broadcom Home Networking Division 10/100 Mbit/s Ethernet ++ * Helix4 sudo EROM ++ * ++ */ ++ ++#ifndef _hx4_erom_h_ ++#define _hx4_erom_h_ ++ ++extern uint32 hx4_erom[]; ++ ++#endif //_hx4_erom_h_ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/kt2_erom.c b/drivers/net/ethernet/broadcom/gmac/src/shared/kt2_erom.c +--- a/drivers/net/ethernet/broadcom/gmac/src/shared/kt2_erom.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/shared/kt2_erom.c 2017-11-09 17:53:44.056295000 +0800 +@@ -0,0 +1,65 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Broadcom Home Networking Division 10/100 Mbit/s Ethernet ++ * Helix4 sudo EROM ++ * ++ */ ++#include ++ ++uint32 kt2_erom[] = { ++ //#define CC_CORE_ID 0x800 /* chipcommon core */ ++ 0x4bf80001, 0x2a004201, 0x18000005, 0x181200c5, ++ //#define NS_CCB_CORE_ID 0x50b /* ChipcommonB core */ ++ 0x4bf50b01, 0x01000201, 0x18001005, 0x18002005, 0x18003005, 0x18004005, 0x18005005, 0x18006005, 0x18007005, 0x18008005, 0x18009005, ++ //#define NS_DMA_CORE_ID 0x502 /* DMA core */ ++ 0x4bf50201, 0x01004211, 0x00000003, 0x1802c005, 0x181140c5, ++ //#define GMAC_CORE_ID 0x82d /* Gigabit MAC core */ ++ 0x4bf82d01, 0x04004211, 0x00000103, 0x18022005, 0x181100c5, ++ 0x4bf82d01, 0x04004211, 0x00000203, 0x18023005, 0x181110c5, ++ //#define NS_PCIEG2_CORE_ID 0x501 /* PCIE Gen 2 core */ ++ 0x4bf50101, 0x01084411, 0x00000503, 0x18012005, 0x08000135, 0x08000000, 0x181010c5, 0x1810a185, ++ 0x4bf50101, 0x01084411, 0x00000603, 0x18013005, 0x40000135, 0x08000000, 0x181020c5, 0x1810b185, ++ 0x4bf50101, 0x01084411, 0x00000703, 0x18014005, 0x48000135, 0x08000000, 0x181030c5, 0x1810c185, ++ //#define ARMCA9_CORE_ID 0x510 /* ARM Cortex A9 core (ihost) */ ++ 0x4bf51001, 0x01104611, 0x00000803, 0x1800b005, 0x1800c005, 0x19000135, 0x00020000, 0x19020235, 0x00003000, 0x181000c5, 0x18106185, 0x18107285, ++ //#define NS_USB20_CORE_ID 0x504 /* USB2.0 core */ ++ 0x4bf50401, 0x01004211, 0x00000903, 0x18021005, 0x18022005, 0x181150c5, ++ //#define NS_USB30_CORE_ID 0x505 /* USB3.0 core */ ++ 0x4bf50501, 0x01004211, 0x00000a03, 0x18023005, 0x181050c5, ++ //#define NS_SDIO3_CORE_ID 0x503 /* SDIO3 core */ ++ 0x4bf50301, 0x01004211, 0x00000b03, 0x18020005, 0x181160c5, ++ //#define I2S_CORE_ID 0x834 /* I2S core */ ++ 0x4bf83401, 0x03004211, 0x00000c03, 0x1802a005, 0x181170c5, ++ //#define NS_A9JTAG_CORE_ID 0x506 /* ARM Cortex A9 JTAG core */ ++ 0x4bf50601, 0x01084211, 0x00000d03, 0x18210035, 0x00010000, 0x181180c5, 0x1811c085, ++ //#define NS_DDR23_CORE_ID 0x507 /* Denali DDR2/DDR3 memory controller */ ++ 0x4bf50701, 0x01100601, 0x18010005, 0x00000135, 0x08000000, 0x80000135, 0x30000000, 0xb0000235, 0x10000000, 0x18108185, 0x18109285, ++ //#define NS_ROM_CORE_ID 0x508 /* ROM core */ ++ 0x4bf50801, 0x01080201, 0xfffd0035, 0x00030000, 0x1810d085, ++ //#define NS_NAND_CORE_ID 0x509 /* NAND flash controller core */ ++ 0x4bf50901, 0x01080401, 0x18028005, 0x1c000135, 0x02000000, 0x1811a185, ++ //#define NS_QSPI_CORE_ID 0x50a /* SPI flash controller core */ ++ 0x4bf50a01, 0x01080401, 0x18029005, 0x1e000135, 0x02000000, 0x1811b185, ++ //#define EROM_CORE_ID 0x366 /* EROM core ID */ ++ 0x43b36601, 0x00000201, 0x18130005, ++ 0x43b13501, 0x00080201, 0x18000075, 0x00010000, 0x18121085, ++ 0x43b30101, 0x01000201, 0x1a000035, 0x00100000, ++ 0x43bfff01, 0x00280a01, 0x10000035, 0x08000000, 0x18011005, 0x18015035, 0x0000b000, 0x1802b105, 0x1802d135, 0x000d3000, 0x18104105, 0x1810e215, ++ 0x18119205, 0x1811d235, 0x00003000, 0x18122335, 0x0000e000, 0x18131305, 0x18137335, 0x000d9000, 0x18220335, 0x000de000, 0x19023335, ++ 0x00fdd000, 0x1a100335, 0x01f00000, 0x20000435, 0x20000000, 0x50000435, 0x30000000, 0xc0000435, 0x3ffd0000, 0x18132085, 0x18133185, ++ 0x18134285, 0x18135385, 0x18136485, ++ 0x0000000f ++}; +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/kt2_erom.h b/drivers/net/ethernet/broadcom/gmac/src/shared/kt2_erom.h +--- a/drivers/net/ethernet/broadcom/gmac/src/shared/kt2_erom.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/shared/kt2_erom.h 2017-11-09 17:53:44.057293000 +0800 +@@ -0,0 +1,26 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Broadcom Home Networking Division 10/100 Mbit/s Ethernet ++ * Helix4 sudo EROM ++ * ++ */ ++ ++#ifndef _kt2_erom_h_ ++#define _kt2_erom_h_ ++ ++extern uint32 kt2_erom[]; ++ ++#endif //_kt2_erom_h_ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/linux_osl.c b/drivers/net/ethernet/broadcom/gmac/src/shared/linux_osl.c +--- a/drivers/net/ethernet/broadcom/gmac/src/shared/linux_osl.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/shared/linux_osl.c 2017-11-09 17:53:44.058299000 +0800 +@@ -0,0 +1,1266 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Linux OS Independent Layer ++ * ++ * $Id: linux_osl.c 322208 2012-03-20 01:53:23Z $ ++ */ ++ ++#define LINUX_PORT ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef mips ++#include ++#endif /* mips */ ++#include ++ ++ ++#include ++#include ++ ++#define PCI_CFG_RETRY 10 ++ ++#define OS_HANDLE_MAGIC 0x1234abcd /* Magic # to recognize osh */ ++#define BCM_MEM_FILENAME_LEN 24 /* Mem. filename length */ ++ ++#ifdef DHD_USE_STATIC_BUF ++#define STATIC_BUF_MAX_NUM 16 ++#define STATIC_BUF_SIZE (PAGE_SIZE*2) ++#define STATIC_BUF_TOTAL_LEN (STATIC_BUF_MAX_NUM * STATIC_BUF_SIZE) ++ ++typedef struct bcm_static_buf { ++ struct semaphore static_sem; ++ unsigned char *buf_ptr; ++ unsigned char buf_use[STATIC_BUF_MAX_NUM]; ++} bcm_static_buf_t; ++ ++static bcm_static_buf_t *bcm_static_buf = 0; ++ ++#define STATIC_PKT_MAX_NUM 8 ++ ++typedef struct bcm_static_pkt { ++ struct sk_buff *skb_4k[STATIC_PKT_MAX_NUM]; ++ struct sk_buff *skb_8k[STATIC_PKT_MAX_NUM]; ++ struct semaphore osl_pkt_sem; ++ unsigned char pkt_use[STATIC_PKT_MAX_NUM * 2]; ++} bcm_static_pkt_t; ++ ++static bcm_static_pkt_t *bcm_static_skb = 0; ++#endif /* DHD_USE_STATIC_BUF */ ++ ++typedef struct bcm_mem_link { ++ struct bcm_mem_link *prev; ++ struct bcm_mem_link *next; ++ uint size; ++ int line; ++ void *osh; ++ char file[BCM_MEM_FILENAME_LEN]; ++} bcm_mem_link_t; ++ ++struct osl_info { ++ osl_pubinfo_t pub; ++ uint magic; ++ void *pdev; ++ atomic_t malloced; ++ atomic_t pktalloced; /* Number of allocated packet buffers */ ++ uint failed; ++ uint bustype; ++ bcm_mem_link_t *dbgmem_list; ++ spinlock_t dbgmem_lock; ++ spinlock_t pktalloc_lock; ++}; ++ ++#define OSL_PKTTAG_CLEAR(p) \ ++do { \ ++ struct sk_buff *s = (struct sk_buff *)(p); \ ++ ASSERT(OSL_PKTTAG_SZ == 32); \ ++ *(uint32 *)(&s->cb[0]) = 0; *(uint32 *)(&s->cb[4]) = 0; \ ++ *(uint32 *)(&s->cb[8]) = 0; *(uint32 *)(&s->cb[12]) = 0; \ ++ *(uint32 *)(&s->cb[16]) = 0; *(uint32 *)(&s->cb[20]) = 0; \ ++ *(uint32 *)(&s->cb[24]) = 0; *(uint32 *)(&s->cb[28]) = 0; \ ++} while (0) ++ ++/* PCMCIA attribute space access macros */ ++#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE) ++struct pcmcia_dev { ++ dev_link_t link; /* PCMCIA device pointer */ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) ++ dev_node_t node; /* PCMCIA node structure */ ++#endif ++ void *base; /* Mapped attribute memory window */ ++ size_t size; /* Size of window */ ++ void *drv; /* Driver data */ ++}; ++#endif /* defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE) */ ++ ++/* Global ASSERT type flag */ ++uint32 g_assert_type = FALSE; ++ ++static int16 linuxbcmerrormap[] = ++{ 0, /* 0 */ ++ -EINVAL, /* BCME_ERROR */ ++ -EINVAL, /* BCME_BADARG */ ++ -EINVAL, /* BCME_BADOPTION */ ++ -EINVAL, /* BCME_NOTUP */ ++ -EINVAL, /* BCME_NOTDOWN */ ++ -EINVAL, /* BCME_NOTAP */ ++ -EINVAL, /* BCME_NOTSTA */ ++ -EINVAL, /* BCME_BADKEYIDX */ ++ -EINVAL, /* BCME_RADIOOFF */ ++ -EINVAL, /* BCME_NOTBANDLOCKED */ ++ -EINVAL, /* BCME_NOCLK */ ++ -EINVAL, /* BCME_BADRATESET */ ++ -EINVAL, /* BCME_BADBAND */ ++ -E2BIG, /* BCME_BUFTOOSHORT */ ++ -E2BIG, /* BCME_BUFTOOLONG */ ++ -EBUSY, /* BCME_BUSY */ ++ -EINVAL, /* BCME_NOTASSOCIATED */ ++ -EINVAL, /* BCME_BADSSIDLEN */ ++ -EINVAL, /* BCME_OUTOFRANGECHAN */ ++ -EINVAL, /* BCME_BADCHAN */ ++ -EFAULT, /* BCME_BADADDR */ ++ -ENOMEM, /* BCME_NORESOURCE */ ++ -EOPNOTSUPP, /* BCME_UNSUPPORTED */ ++ -EMSGSIZE, /* BCME_BADLENGTH */ ++ -EINVAL, /* BCME_NOTREADY */ ++ -EPERM, /* BCME_EPERM */ ++ -ENOMEM, /* BCME_NOMEM */ ++ -EINVAL, /* BCME_ASSOCIATED */ ++ -ERANGE, /* BCME_RANGE */ ++ -EINVAL, /* BCME_NOTFOUND */ ++ -EINVAL, /* BCME_WME_NOT_ENABLED */ ++ -EINVAL, /* BCME_TSPEC_NOTFOUND */ ++ -EINVAL, /* BCME_ACM_NOTSUPPORTED */ ++ -EINVAL, /* BCME_NOT_WME_ASSOCIATION */ ++ -EIO, /* BCME_SDIO_ERROR */ ++ -ENODEV, /* BCME_DONGLE_DOWN */ ++ -EINVAL, /* BCME_VERSION */ ++ -EIO, /* BCME_TXFAIL */ ++ -EIO, /* BCME_RXFAIL */ ++ -ENODEV, /* BCME_NODEVICE */ ++ -EINVAL, /* BCME_NMODE_DISABLED */ ++ -ENODATA, /* BCME_NONRESIDENT */ ++ ++/* When an new error code is added to bcmutils.h, add os ++ * specific error translation here as well ++ */ ++/* check if BCME_LAST changed since the last time this function was updated */ ++#if BCME_LAST != -42 ++#error "You need to add a OS error translation in the linuxbcmerrormap \ ++ for new error code defined in bcmutils.h" ++#endif ++}; ++ ++/* translate bcmerrors into linux errors */ ++int ++osl_error(int bcmerror) ++{ ++ if (bcmerror > 0) ++ bcmerror = 0; ++ else if (bcmerror < BCME_LAST) ++ bcmerror = BCME_ERROR; ++ ++ /* Array bounds covered by ASSERT in osl_attach */ ++ return linuxbcmerrormap[-bcmerror]; ++} ++ ++extern uint8* dhd_os_prealloc(void *osh, int section, int size); ++ ++EXPORT_SYMBOL(osl_attach); ++osl_t * ++osl_attach(void *pdev, uint bustype, bool pkttag) ++{ ++ osl_t *osh; ++ ++ osh = kmalloc(sizeof(osl_t), GFP_ATOMIC); ++ ASSERT(osh); ++ ++ bzero(osh, sizeof(osl_t)); ++ ++ /* Check that error map has the right number of entries in it */ ++ ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(linuxbcmerrormap) - 1)); ++ ++ osh->magic = OS_HANDLE_MAGIC; ++ atomic_set(&osh->malloced, 0); ++ osh->failed = 0; ++ osh->dbgmem_list = NULL; ++ spin_lock_init(&(osh->dbgmem_lock)); ++ osh->pdev = pdev; ++ osh->pub.pkttag = pkttag; ++ osh->bustype = bustype; ++ ++ switch (bustype) { ++ case PCI_BUS: ++ case SI_BUS: ++ case PCMCIA_BUS: ++ osh->pub.mmbus = TRUE; ++ break; ++ case JTAG_BUS: ++ case SDIO_BUS: ++ case USB_BUS: ++ case SPI_BUS: ++ case RPC_BUS: ++ osh->pub.mmbus = FALSE; ++ break; ++ default: ++ ASSERT(FALSE); ++ break; ++ } ++ ++#if defined(DHD_USE_STATIC_BUF) ++ if (!bcm_static_buf) { ++ if (!(bcm_static_buf = (bcm_static_buf_t *)dhd_os_prealloc(osh, 3, STATIC_BUF_SIZE+ ++ STATIC_BUF_TOTAL_LEN))) { ++ printk("can not alloc static buf!\n"); ++ } ++ else ++ printk("alloc static buf at %x!\n", (unsigned int)bcm_static_buf); ++ ++ ++ sema_init(&bcm_static_buf->static_sem, 1); ++ ++ bcm_static_buf->buf_ptr = (unsigned char *)bcm_static_buf + STATIC_BUF_SIZE; ++ } ++ ++ if (!bcm_static_skb) { ++ int i; ++ void *skb_buff_ptr = 0; ++ bcm_static_skb = (bcm_static_pkt_t *)((char *)bcm_static_buf + 2048); ++ skb_buff_ptr = dhd_os_prealloc(osh, 4, 0); ++ ++ bcopy(skb_buff_ptr, bcm_static_skb, sizeof(struct sk_buff *)*16); ++ for (i = 0; i < STATIC_PKT_MAX_NUM * 2; i++) ++ bcm_static_skb->pkt_use[i] = 0; ++ ++ sema_init(&bcm_static_skb->osl_pkt_sem, 1); ++ } ++#endif /* DHD_USE_STATIC_BUF */ ++ ++ spin_lock_init(&(osh->pktalloc_lock)); ++ ++#ifdef BCMDBG ++ if (pkttag) { ++ struct sk_buff *skb; ++ ASSERT(OSL_PKTTAG_SZ <= sizeof(skb->cb)); ++ } ++#endif ++ return osh; ++} ++ ++void ++osl_detach(osl_t *osh) ++{ ++ if (osh == NULL) ++ return; ++ ++#ifdef DHD_USE_STATIC_BUF ++ if (bcm_static_buf) { ++ bcm_static_buf = 0; ++ } ++ if (bcm_static_skb) { ++ bcm_static_skb = 0; ++ } ++#endif ++ ++ ASSERT(osh->magic == OS_HANDLE_MAGIC); ++ kfree(osh); ++} ++ ++static struct sk_buff *osl_alloc_skb(unsigned int len) ++{ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25) ++ gfp_t flags = GFP_ATOMIC; ++ ++ return __dev_alloc_skb(len, flags); ++#else ++ return dev_alloc_skb(len); ++#endif ++} ++ ++/* Convert a driver packet to native(OS) packet ++ * In the process, packettag is zeroed out before sending up ++ * IP code depends on skb->cb to be setup correctly with various options ++ * In our case, that means it should be 0 ++ */ ++struct sk_buff * BCMFASTPATH ++osl_pkt_tonative(osl_t *osh, void *pkt) ++{ ++ struct sk_buff *nskb; ++ ++ if (osh->pub.pkttag) ++ OSL_PKTTAG_CLEAR(pkt); ++ ++ /* Decrement the packet counter */ ++ for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) { ++ atomic_sub(PKTISCHAINED(nskb) ? PKTCCNT(nskb) : 1, &osh->pktalloced); ++ } ++ return (struct sk_buff *)pkt; ++} ++ ++/* Convert a native(OS) packet to driver packet. ++ * In the process, native packet is destroyed, there is no copying ++ * Also, a packettag is zeroed out ++ */ ++void * BCMFASTPATH ++osl_pkt_frmnative(osl_t *osh, void *pkt) ++{ ++ struct sk_buff *nskb; ++ ++ if (osh->pub.pkttag) ++ OSL_PKTTAG_CLEAR(pkt); ++ ++ /* Increment the packet counter */ ++ for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) { ++ atomic_add(PKTISCHAINED(nskb) ? PKTCCNT(nskb) : 1, &osh->pktalloced); ++ } ++ return (void *)pkt; ++} ++ ++/* Return a new packet. zero out pkttag */ ++void * BCMFASTPATH ++osl_pktget(osl_t *osh, uint len) ++{ ++ struct sk_buff *skb; ++ ++ if ((skb = osl_alloc_skb(len))) { ++ skb_put(skb, len); ++ skb->priority = 0; ++ ++ atomic_inc(&osh->pktalloced); ++ } ++ ++ PKTSETCLINK(skb, NULL); ++ ++ return ((void*) skb); ++} ++ ++/* Free the driver packet. Free the tag if present */ ++void BCMFASTPATH ++osl_pktfree(osl_t *osh, void *p, bool send) ++{ ++ struct sk_buff *skb, *nskb; ++ ++ skb = (struct sk_buff*) p; ++ ++ if (send && osh->pub.tx_fn) ++ osh->pub.tx_fn(osh->pub.tx_ctx, p, 0); ++ ++ PKTDBG_TRACE(osh, (void *) skb, PKTLIST_PKTFREE); ++ ++ /* perversion: we use skb->next to chain multi-skb packets */ ++ while (skb) { ++ nskb = skb->next; ++ skb->next = NULL; ++ ++ ++ { ++ if (skb->destructor) ++ /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if ++ * destructor exists ++ */ ++ dev_kfree_skb_any(skb); ++ else ++ /* can free immediately (even in_irq()) if destructor ++ * does not exist ++ */ ++ dev_kfree_skb(skb); ++ } ++ atomic_dec(&osh->pktalloced); ++ skb = nskb; ++ } ++} ++ ++#ifdef DHD_USE_STATIC_BUF ++void* ++osl_pktget_static(osl_t *osh, uint len) ++{ ++ int i = 0; ++ struct sk_buff *skb; ++ ++ if (len > (PAGE_SIZE*2)) { ++ printk("%s: attempt to allocate huge packet (0x%x)\n", __FUNCTION__, len); ++ return osl_pktget(osh, len); ++ } ++ ++ down(&bcm_static_skb->osl_pkt_sem); ++ ++ if (len <= PAGE_SIZE) { ++ for (i = 0; i < STATIC_PKT_MAX_NUM; i++) { ++ if (bcm_static_skb->pkt_use[i] == 0) ++ break; ++ } ++ ++ if (i != STATIC_PKT_MAX_NUM) { ++ bcm_static_skb->pkt_use[i] = 1; ++ up(&bcm_static_skb->osl_pkt_sem); ++ skb = bcm_static_skb->skb_4k[i]; ++ skb->tail = skb->data + len; ++ skb->len = len; ++ return skb; ++ } ++ } ++ ++ ++ for (i = 0; i < STATIC_PKT_MAX_NUM; i++) { ++ if (bcm_static_skb->pkt_use[i+STATIC_PKT_MAX_NUM] == 0) ++ break; ++ } ++ ++ if (i != STATIC_PKT_MAX_NUM) { ++ bcm_static_skb->pkt_use[i+STATIC_PKT_MAX_NUM] = 1; ++ up(&bcm_static_skb->osl_pkt_sem); ++ skb = bcm_static_skb->skb_8k[i]; ++ skb->tail = skb->data + len; ++ skb->len = len; ++ return skb; ++ } ++ ++ up(&bcm_static_skb->osl_pkt_sem); ++ printk("%s: all static pkt in use!\n", __FUNCTION__); ++ return osl_pktget(osh, len); ++} ++ ++void ++osl_pktfree_static(osl_t *osh, void *p, bool send) ++{ ++ int i; ++ ++ for (i = 0; i < STATIC_PKT_MAX_NUM; i++) { ++ if (p == bcm_static_skb->skb_4k[i]) { ++ down(&bcm_static_skb->osl_pkt_sem); ++ bcm_static_skb->pkt_use[i] = 0; ++ up(&bcm_static_skb->osl_pkt_sem); ++ return; ++ } ++ } ++ ++ for (i = 0; i < STATIC_PKT_MAX_NUM; i++) { ++ if (p == bcm_static_skb->skb_8k[i]) { ++ down(&bcm_static_skb->osl_pkt_sem); ++ bcm_static_skb->pkt_use[i + STATIC_PKT_MAX_NUM] = 0; ++ up(&bcm_static_skb->osl_pkt_sem); ++ return; ++ } ++ } ++ ++ return osl_pktfree(osh, p, send); ++} ++#endif /* DHD_USE_STATIC_BUF */ ++ ++uint32 ++osl_pci_read_config(osl_t *osh, uint offset, uint size) ++{ ++ uint val = 0; ++ uint retry = PCI_CFG_RETRY; ++ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ ++ /* only 4byte access supported */ ++ ASSERT(size == 4); ++ ++ do { ++ pci_read_config_dword(osh->pdev, offset, &val); ++ if (val != 0xffffffff) ++ break; ++ } while (retry--); ++ ++#ifdef BCMDBG ++ if (retry < PCI_CFG_RETRY) ++ printk("PCI CONFIG READ access to %d required %d retries\n", offset, ++ (PCI_CFG_RETRY - retry)); ++#endif /* BCMDBG */ ++ ++ return (val); ++} ++ ++void ++osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val) ++{ ++ uint retry = PCI_CFG_RETRY; ++ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ ++ /* only 4byte access supported */ ++ ASSERT(size == 4); ++ ++ do { ++ pci_write_config_dword(osh->pdev, offset, val); ++ if (offset != PCI_BAR0_WIN) ++ break; ++ if (osl_pci_read_config(osh, offset, size) == val) ++ break; ++ } while (retry--); ++ ++#ifdef BCMDBG ++ if (retry < PCI_CFG_RETRY) ++ printk("PCI CONFIG WRITE access to %d required %d retries\n", offset, ++ (PCI_CFG_RETRY - retry)); ++#endif /* BCMDBG */ ++} ++ ++/* return bus # for the pci device pointed by osh->pdev */ ++uint ++osl_pci_bus(osl_t *osh) ++{ ++ ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); ++ ++ return ((struct pci_dev *)osh->pdev)->bus->number; ++} ++ ++/* return slot # for the pci device pointed by osh->pdev */ ++uint ++osl_pci_slot(osl_t *osh) ++{ ++ ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); ++ ++ return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn); ++} ++ ++/* return the pci device pointed by osh->pdev */ ++struct pci_dev * ++osl_pci_device(osl_t *osh) ++{ ++ ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); ++ ++ return osh->pdev; ++} ++ ++static void ++osl_pcmcia_attr(osl_t *osh, uint offset, char *buf, int size, bool write) ++{ ++} ++ ++void ++osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size) ++{ ++ osl_pcmcia_attr(osh, offset, (char *) buf, size, FALSE); ++} ++ ++void ++osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size) ++{ ++ osl_pcmcia_attr(osh, offset, (char *) buf, size, TRUE); ++} ++ ++void * ++osl_malloc(osl_t *osh, uint size) ++{ ++ void *addr; ++ ++ /* only ASSERT if osh is defined */ ++ if (osh) ++ ASSERT(osh->magic == OS_HANDLE_MAGIC); ++ ++#ifdef DHD_USE_STATIC_BUF ++ if (bcm_static_buf) ++ { ++ int i = 0; ++ if ((size >= PAGE_SIZE)&&(size <= STATIC_BUF_SIZE)) ++ { ++ down(&bcm_static_buf->static_sem); ++ ++ for (i = 0; i < STATIC_BUF_MAX_NUM; i++) ++ { ++ if (bcm_static_buf->buf_use[i] == 0) ++ break; ++ } ++ ++ if (i == STATIC_BUF_MAX_NUM) ++ { ++ up(&bcm_static_buf->static_sem); ++ printk("all static buff in use!\n"); ++ goto original; ++ } ++ ++ bcm_static_buf->buf_use[i] = 1; ++ up(&bcm_static_buf->static_sem); ++ ++ bzero(bcm_static_buf->buf_ptr+STATIC_BUF_SIZE*i, size); ++ if (osh) ++ atomic_add(size, &osh->malloced); ++ ++ return ((void *)(bcm_static_buf->buf_ptr+STATIC_BUF_SIZE*i)); ++ } ++ } ++original: ++#endif /* DHD_USE_STATIC_BUF */ ++ ++ if ((addr = kmalloc(size, GFP_ATOMIC)) == NULL) { ++ if (osh) ++ osh->failed++; ++ return (NULL); ++ } ++ if (osh) ++ atomic_add(size, &osh->malloced); ++ ++ return (addr); ++} ++ ++void ++osl_mfree(osl_t *osh, void *addr, uint size) ++{ ++#ifdef DHD_USE_STATIC_BUF ++ if (bcm_static_buf) ++ { ++ if ((addr > (void *)bcm_static_buf) && ((unsigned char *)addr ++ <= ((unsigned char *)bcm_static_buf + STATIC_BUF_TOTAL_LEN))) ++ { ++ int buf_idx = 0; ++ ++ buf_idx = ((unsigned char *)addr - bcm_static_buf->buf_ptr)/STATIC_BUF_SIZE; ++ ++ down(&bcm_static_buf->static_sem); ++ bcm_static_buf->buf_use[buf_idx] = 0; ++ up(&bcm_static_buf->static_sem); ++ ++ if (osh) { ++ ASSERT(osh->magic == OS_HANDLE_MAGIC); ++ atomic_sub(size, &osh->malloced); ++ } ++ return; ++ } ++ } ++#endif /* DHD_USE_STATIC_BUF */ ++ if (osh) { ++ ASSERT(osh->magic == OS_HANDLE_MAGIC); ++ atomic_sub(size, &osh->malloced); ++ } ++ kfree(addr); ++} ++ ++uint ++osl_malloced(osl_t *osh) ++{ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ return (atomic_read(&osh->malloced)); ++} ++ ++uint ++osl_malloc_failed(osl_t *osh) ++{ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ return (osh->failed); ++} ++ ++ ++uint ++osl_dma_consistent_align(void) ++{ ++ return (PAGE_SIZE); ++} ++ ++void* ++osl_dma_alloc_consistent(osl_t *osh, uint size, uint16 align_bits, uint *alloced, ulong *pap) ++{ ++#ifdef CONFIG_BCM_IPROC_GMAC_ACP ++ void *va; ++ uint16 align = (1 << align_bits); ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ ++ if (!ISALIGNED(DMA_CONSISTENT_ALIGN, align)) ++ size += align; ++ *alloced = size; ++ ++ va = kmalloc(size, GFP_ATOMIC | __GFP_ZERO); ++ if (va) ++ *pap = (ulong)__virt_to_phys((ulong)va); ++ return va; ++ ++#else ++ void *ret; ++// int gfp = GFP_KERNEL; //GFP_ATOMIC | GFP_DMA; ++ /* platform device reference */ ++ struct platform_device *pdev; ++ ++ uint16 align = (1 << align_bits); ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ ++ if (!ISALIGNED(DMA_CONSISTENT_ALIGN, align)) ++ size += align; ++ *alloced = size; ++ ++// ret = (void *)__get_free_pages(gfp, get_order(size)); ++// if (ret != NULL) { ++// memset(ret, 0, size); ++// *pap = virt_to_phys(ret); ++// } ++ pdev = (struct platform_device *)osh->pdev; ++ ret = dma_alloc_coherent(&pdev->dev, size, (dma_addr_t*)pap, GFP_KERNEL); ++ return ret; ++ ++#endif /* CONFIG_BCM_IPROC_GMAC_ACP */ ++} ++ ++void ++osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa) ++{ ++#ifdef CONFIG_BCM_IPROC_GMAC_ACP ++ kfree(va); ++#else ++ /* platform device reference */ ++ struct platform_device *pdev; ++ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ ++// free_pages((unsigned long)va, get_order(size)); ++ pdev = (struct platform_device *)osh->pdev; ++ dma_free_coherent(&pdev->dev, size, va, (dma_addr_t)pa); ++#endif /* CONFIG_BCM_IPROC_GMAC_ACP */ ++} ++ ++uint BCMFASTPATH ++osl_dma_map(osl_t *osh, void *va, uint size, int direction, void *p, hnddma_seg_map_t *dmah) ++{ ++ int dir; ++ /* platform device reference */ ++ struct platform_device *pdev; ++ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ pdev = (struct platform_device *)osh->pdev; ++ dir = (direction == DMA_TX)? DMA_TO_DEVICE: DMA_FROM_DEVICE; ++ ++#if defined(BCMDMASGLISTOSL) ++ if (dmah != NULL) { ++ int32 nsegs, i, totsegs = 0, totlen = 0; ++ struct scatterlist *sg, _sg[MAX_DMA_SEGS * 2]; ++ struct sk_buff *skb; ++ for (skb = (struct sk_buff *)p; skb != NULL; skb = PKTNEXT(osh, skb)) { ++ sg = &_sg[totsegs]; ++ if (skb_is_nonlinear(skb)) { ++ nsegs = skb_to_sgvec(skb, sg, 0, PKTLEN(osh, skb)); ++ ASSERT((nsegs > 0) && (totsegs + nsegs <= MAX_DMA_SEGS)); ++ #ifndef CONFIG_BCM_IPROC_GMAC_ACP ++ dma_map_sg(&pdev->dev, sg, nsegs, dir); ++ #endif /* CONFIG_BCM_IPROC_GMAC_ACP */ ++ } else { ++ nsegs = 1; ++ ASSERT(totsegs + nsegs <= MAX_DMA_SEGS); ++ sg->page_link = 0; ++ sg_set_buf(sg, PKTDATA(osh, skb), PKTLEN(osh, skb)); ++ #ifndef CONFIG_BCM_IPROC_GMAC_ACP ++ dma_map_single(&pdev->dev, PKTDATA(osh, skb), PKTLEN(osh, skb), dir); ++ #endif /* CONFIG_BCM_IPROC_GMAC_ACP */ ++ } ++ totsegs += nsegs; ++ totlen += PKTLEN(osh, skb); ++ } ++ dmah->nsegs = totsegs; ++ dmah->origsize = totlen; ++ for (i = 0, sg = _sg; i < totsegs; i++, sg++) { ++ dmah->segs[i].addr = sg_phys(sg); ++ dmah->segs[i].length = sg->length; ++ } ++ #ifdef CONFIG_BCM_IPROC_GMAC_ACP ++ return virt_to_phys(va); ++ #else ++ return dmah->segs[0].addr; ++ #endif /* CONFIG_BCM_IPROC_GMAC_ACP */ ++ } ++#endif /* defined(BCMDMASGLISTOSL) */ ++ ++#ifdef CONFIG_BCM_IPROC_GMAC_ACP ++ return virt_to_phys(va); ++#else ++ return dma_map_single(&pdev->dev, va, size, dir); ++#endif /* CONFIG_BCM_IPROC_GMAC_ACP */ ++} ++ ++void BCMFASTPATH ++osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction) ++{ ++#ifndef CONFIG_BCM_IPROC_GMAC_ACP ++ int dir; ++ /* platform device reference */ ++ struct platform_device *pdev; ++ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ pdev = (struct platform_device *)osh->pdev; ++ dir = (direction == DMA_TX)? DMA_TO_DEVICE: DMA_FROM_DEVICE; ++ dma_unmap_single(&pdev->dev, (uint32)pa, size, dir); ++#endif /* ! CONFIG_BCM_IPROC_GMAC_ACP */ ++} ++ ++ ++void ++osl_delay(uint usec) ++{ ++ uint d; ++ ++ while (usec > 0) { ++ d = MIN(usec, 1000); ++ udelay(d); ++ usec -= d; ++ } ++} ++ ++/* Clone a packet. ++ * The pkttag contents are NOT cloned. ++ */ ++void * ++osl_pktdup(osl_t *osh, void *skb) ++{ ++ void * p; ++ ++ /* clear the CTFBUF flag if set and map the rest of the buffer ++ * before cloning. ++ */ ++ PKTCTFMAP(osh, skb); ++ ++ if ((p = skb_clone((struct sk_buff *)skb, GFP_ATOMIC)) == NULL) ++ return NULL; ++ ++ /* skb_clone copies skb->cb.. we don't want that */ ++ if (osh->pub.pkttag) ++ OSL_PKTTAG_CLEAR(p); ++ ++ /* Increment the packet counter */ ++ atomic_inc(&osh->pktalloced); ++ return (p); ++} ++ ++ ++/* ++ * OSLREGOPS specifies the use of osl_XXX routines to be used for register access ++ */ ++#ifdef OSLREGOPS ++uint8 ++osl_readb(osl_t *osh, volatile uint8 *r) ++{ ++ osl_rreg_fn_t rreg = ((osl_pubinfo_t*)osh)->rreg_fn; ++ void *ctx = ((osl_pubinfo_t*)osh)->reg_ctx; ++ ++ return (uint8)((rreg)(ctx, (void*)r, sizeof(uint8))); ++} ++ ++ ++uint16 ++osl_readw(osl_t *osh, volatile uint16 *r) ++{ ++ osl_rreg_fn_t rreg = ((osl_pubinfo_t*)osh)->rreg_fn; ++ void *ctx = ((osl_pubinfo_t*)osh)->reg_ctx; ++ ++ return (uint16)((rreg)(ctx, (void*)r, sizeof(uint16))); ++} ++ ++uint32 ++osl_readl(osl_t *osh, volatile uint32 *r) ++{ ++ osl_rreg_fn_t rreg = ((osl_pubinfo_t*)osh)->rreg_fn; ++ void *ctx = ((osl_pubinfo_t*)osh)->reg_ctx; ++ ++ return (uint32)((rreg)(ctx, (void*)r, sizeof(uint32))); ++} ++ ++void ++osl_writeb(osl_t *osh, volatile uint8 *r, uint8 v) ++{ ++ osl_wreg_fn_t wreg = ((osl_pubinfo_t*)osh)->wreg_fn; ++ void *ctx = ((osl_pubinfo_t*)osh)->reg_ctx; ++ ++ ((wreg)(ctx, (void*)r, v, sizeof(uint8))); ++} ++ ++ ++void ++osl_writew(osl_t *osh, volatile uint16 *r, uint16 v) ++{ ++ osl_wreg_fn_t wreg = ((osl_pubinfo_t*)osh)->wreg_fn; ++ void *ctx = ((osl_pubinfo_t*)osh)->reg_ctx; ++ ++ ((wreg)(ctx, (void*)r, v, sizeof(uint16))); ++} ++ ++void ++osl_writel(osl_t *osh, volatile uint32 *r, uint32 v) ++{ ++ osl_wreg_fn_t wreg = ((osl_pubinfo_t*)osh)->wreg_fn; ++ void *ctx = ((osl_pubinfo_t*)osh)->reg_ctx; ++ ++ ((wreg)(ctx, (void*)r, v, sizeof(uint32))); ++} ++#endif /* OSLREGOPS */ ++ ++/* ++ * BINOSL selects the slightly slower function-call-based binary compatible osl. ++ */ ++#ifdef BINOSL ++ ++uint32 ++osl_sysuptime(void) ++{ ++ return ((uint32)jiffies * (1000 / HZ)); ++} ++ ++int ++osl_printf(const char *format, ...) ++{ ++ va_list args; ++ static char printbuf[1024]; ++ int len; ++ ++ /* sprintf into a local buffer because there *is* no "vprintk()".. */ ++ va_start(args, format); ++ len = vsnprintf(printbuf, 1024, format, args); ++ va_end(args); ++ ++ if (len > sizeof(printbuf)) { ++ printk("osl_printf: buffer overrun\n"); ++ return (0); ++ } ++ ++ return (printk("%s", printbuf)); ++} ++ ++int ++osl_sprintf(char *buf, const char *format, ...) ++{ ++ va_list args; ++ int rc; ++ ++ va_start(args, format); ++ rc = vsprintf(buf, format, args); ++ va_end(args); ++ return (rc); ++} ++ ++int ++osl_snprintf(char *buf, size_t n, const char *format, ...) ++{ ++ va_list args; ++ int rc; ++ ++ va_start(args, format); ++ rc = vsnprintf(buf, n, format, args); ++ va_end(args); ++ return (rc); ++} ++ ++int ++osl_vsprintf(char *buf, const char *format, va_list ap) ++{ ++ return (vsprintf(buf, format, ap)); ++} ++ ++int ++osl_vsnprintf(char *buf, size_t n, const char *format, va_list ap) ++{ ++ return (vsnprintf(buf, n, format, ap)); ++} ++ ++int ++osl_strcmp(const char *s1, const char *s2) ++{ ++ return (strcmp(s1, s2)); ++} ++ ++int ++osl_strncmp(const char *s1, const char *s2, uint n) ++{ ++ return (strncmp(s1, s2, n)); ++} ++ ++int ++osl_strlen(const char *s) ++{ ++ return (strlen(s)); ++} ++ ++char* ++osl_strcpy(char *d, const char *s) ++{ ++ return (strcpy(d, s)); ++} ++ ++char* ++osl_strncpy(char *d, const char *s, uint n) ++{ ++ return (strncpy(d, s, n)); ++} ++ ++char* ++osl_strchr(const char *s, int c) ++{ ++ return (strchr(s, c)); ++} ++ ++char* ++osl_strrchr(const char *s, int c) ++{ ++ return (strrchr(s, c)); ++} ++ ++void* ++osl_memset(void *d, int c, size_t n) ++{ ++ return memset(d, c, n); ++} ++ ++void* ++osl_memcpy(void *d, const void *s, size_t n) ++{ ++ return memcpy(d, s, n); ++} ++ ++void* ++osl_memmove(void *d, const void *s, size_t n) ++{ ++ return memmove(d, s, n); ++} ++ ++int ++osl_memcmp(const void *s1, const void *s2, size_t n) ++{ ++ return memcmp(s1, s2, n); ++} ++ ++uint32 ++osl_readl(volatile uint32 *r) ++{ ++ return (readl(r)); ++} ++ ++uint16 ++osl_readw(volatile uint16 *r) ++{ ++ return (readw(r)); ++} ++ ++uint8 ++osl_readb(volatile uint8 *r) ++{ ++ return (readb(r)); ++} ++ ++void ++osl_writel(uint32 v, volatile uint32 *r) ++{ ++ writel(v, r); ++} ++ ++void ++osl_writew(uint16 v, volatile uint16 *r) ++{ ++ writew(v, r); ++} ++ ++void ++osl_writeb(uint8 v, volatile uint8 *r) ++{ ++ writeb(v, r); ++} ++ ++void * ++osl_uncached(void *va) ++{ ++#ifdef mips ++ return ((void*)KSEG1ADDR(va)); ++#else ++ return ((void*)va); ++#endif /* mips */ ++} ++ ++void * ++osl_cached(void *va) ++{ ++#ifdef mips ++ return ((void*)KSEG0ADDR(va)); ++#else ++ return ((void*)va); ++#endif /* mips */ ++} ++ ++uint ++osl_getcycles(void) ++{ ++ uint cycles; ++ ++#if defined(mips) ++ cycles = read_c0_count() * 2; ++#elif defined(__i386__) ++ rdtscl(cycles); ++#else ++ cycles = 0; ++#endif /* defined(mips) */ ++ return cycles; ++} ++ ++void * ++osl_reg_map(uint32 pa, uint size) ++{ ++ return (ioremap_nocache((unsigned long)pa, (unsigned long)size)); ++} ++ ++void ++osl_reg_unmap(void *va) ++{ ++ iounmap(va); ++} ++ ++int ++osl_busprobe(uint32 *val, uint32 addr) ++{ ++#ifdef mips ++ return get_dbe(*val, (uint32 *)addr); ++#else ++ *val = readl((uint32 *)(uintptr)addr); ++ return 0; ++#endif /* mips */ ++} ++ ++bool ++osl_pktshared(void *skb) ++{ ++ return (((struct sk_buff*)skb)->cloned); ++} ++ ++uchar* ++osl_pktdata(osl_t *osh, void *skb) ++{ ++ return (((struct sk_buff*)skb)->data); ++} ++ ++uint ++osl_pktlen(osl_t *osh, void *skb) ++{ ++ return (((struct sk_buff*)skb)->len); ++} ++ ++uint ++osl_pktheadroom(osl_t *osh, void *skb) ++{ ++ return (uint) skb_headroom((struct sk_buff *) skb); ++} ++ ++uint ++osl_pkttailroom(osl_t *osh, void *skb) ++{ ++ return (uint) skb_tailroom((struct sk_buff *) skb); ++} ++ ++void* ++osl_pktnext(osl_t *osh, void *skb) ++{ ++ return (((struct sk_buff*)skb)->next); ++} ++ ++void ++osl_pktsetnext(void *skb, void *x) ++{ ++ ((struct sk_buff*)skb)->next = (struct sk_buff*)x; ++} ++ ++void ++osl_pktsetlen(osl_t *osh, void *skb, uint len) ++{ ++ __pskb_trim((struct sk_buff*)skb, len); ++} ++ ++uchar* ++osl_pktpush(osl_t *osh, void *skb, int bytes) ++{ ++ return (skb_push((struct sk_buff*)skb, bytes)); ++} ++ ++uchar* ++osl_pktpull(osl_t *osh, void *skb, int bytes) ++{ ++ return (skb_pull((struct sk_buff*)skb, bytes)); ++} ++ ++void* ++osl_pkttag(void *skb) ++{ ++ return ((void*)(((struct sk_buff*)skb)->cb)); ++} ++ ++void* ++osl_pktlink(void *skb) ++{ ++ return (((struct sk_buff*)skb)->prev); ++} ++ ++void ++osl_pktsetlink(void *skb, void *x) ++{ ++ ((struct sk_buff*)skb)->prev = (struct sk_buff*)x; ++} ++ ++uint ++osl_pktprio(void *skb) ++{ ++ return (((struct sk_buff*)skb)->priority); ++} ++ ++void ++osl_pktsetprio(void *skb, uint x) ++{ ++ ((struct sk_buff*)skb)->priority = x; ++} ++#endif /* BINOSL */ ++ ++uint ++osl_pktalloced(osl_t *osh) ++{ ++ return (atomic_read(&osh->pktalloced)); ++} ++ ++/* Linux Kernel: File Operations: start */ ++void * ++osl_os_open_image(char *filename) ++{ ++ struct file *fp; ++ ++ fp = filp_open(filename, O_RDONLY, 0); ++ /* ++ * 2.6.11 (FC4) supports filp_open() but later revs don't? ++ * Alternative: ++ * fp = open_namei(AT_FDCWD, filename, O_RD, 0); ++ * ??? ++ */ ++ if (IS_ERR(fp)) ++ fp = NULL; ++ ++ return fp; ++} ++ ++int ++osl_os_get_image_block(char *buf, int len, void *image) ++{ ++ struct file *fp = (struct file *)image; ++ int rdlen; ++ ++ if (!image) ++ return 0; ++ ++ rdlen = kernel_read(fp, fp->f_pos, buf, len); ++ if (rdlen > 0) ++ fp->f_pos += rdlen; ++ ++ return rdlen; ++} ++ ++void ++osl_os_close_image(void *image) ++{ ++ if (image) ++ filp_close((struct file *)image, NULL); ++} ++/* Linux Kernel: File Operations: end */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/nvramstubs.c b/drivers/net/ethernet/broadcom/gmac/src/shared/nvramstubs.c +--- a/drivers/net/ethernet/broadcom/gmac/src/shared/nvramstubs.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/shared/nvramstubs.c 2017-11-09 17:53:44.059297000 +0800 +@@ -0,0 +1,341 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ * ++ * Stubs for NVRAM functions for platforms without flash ++ * ++ * $Id: nvramstubs.c 325991 2012-04-05 10:16:42Z kenlo $ ++ */ ++ ++#include ++#include ++#include ++#undef strcmp ++#define strcmp(s1,s2) 0 /* always match */ ++#include ++ ++int ++nvram_init(void *sih) ++{ ++ return 0; ++} ++ ++int ++nvram_append(void *sb, char *vars, uint varsz) ++{ ++ return 0; ++} ++ ++void ++nvram_exit(void *sih) ++{ ++} ++ ++/* fake nvram tuples */ ++typedef struct { ++ char *name; ++ char *value; ++} nvram_t; ++ ++static nvram_t fake_nvram[] = { ++ {"boardtype", "0x058d"}, ++ {"boardnum", "0x010"}, ++ {"boardrev", "0x1100"}, ++ {"boardflags", "0x710"}, ++ {"boardflags2", "0"}, ++ {"sromrev", "8"}, ++ {"clkfreq", "133,133,133"}, ++ {"xtalfreq", "125000"}, ++ {"et_txq_thresh", "1024"}, ++ {"et_rx_rate_limit","1"}, ++ {"sdram_config", "0x103"}, ++ {"swgmacet", "et2"}, ++ {"brcmtag", "1"}, ++ //{"ethaddr", "00:90:4c:06:a5:72"}, ++#ifdef FOUR_PORT_CONFIG ++ {"vlan1hwname", "et2"}, ++ {"vlan1ports", "0 1 2 8*"}, ++ {"vlan2hwname", "et2"}, ++ {"vlan2ports", "3 8*"}, ++ {"wanport", "3"}, ++#else ++ {"vlan1hwname", "et2"}, ++ {"vlan1ports", "0 1 2 3 8*"}, ++ {"vlan2hwname", "et2"}, ++ {"vlan2ports", "4 8*"}, ++ {"wanport", "4"}, ++#endif ++ {"landevs", "vlan1"}, ++ {"wandevs", "et0"}, ++ {"lan_ipaddr", "192.168.1.1"}, ++ {"lan_netmask", "255.255.255.0"}, ++ {"boot_wait", "on"}, ++ {"wait_time", "3"}, ++ {"watchdog", "0"}, ++ {"et_msglevel", "0xFFFFFFFF"} ++}; ++#define fake_nvram_size sizeof(fake_nvram)/sizeof(fake_nvram[0]) ++ ++#ifndef FAKE_NVRAM ++ ++#if defined(CONFIG_MACH_IPROC_P7) ++#define CONFIG_SPI_BASE 0xf0000000 ++#else ++#define CONFIG_SPI_BASE 0x1e000000 ++#endif /* CONFIG_MACH_IPROC_P7 */ ++#define CONFIG_ENV_OFFSET 0xc0000 /* 30000-b0000 - use last 10000 for env */ ++#define CONFIG_ENV_SIZE 0x10000 /* 64K */ ++#define CONFIG_ENV_MAX_ENTRIES 512 ++ ++#define UBOOT_ENV_ADDR CONFIG_SPI_BASE+CONFIG_ENV_OFFSET ++#define UBOOT_ENV_SIZE CONFIG_ENV_SIZE ++#define UBOOT_ENV_MAX_NUM CONFIG_ENV_MAX_ENTRIES ++ ++static uint8 u_boot_env[UBOOT_ENV_SIZE]; ++static bool u_boot_env_loaded=false; ++static nvram_t env_list[UBOOT_ENV_MAX_NUM]; ++static int uboot_vars_start = UBOOT_ENV_ADDR; ++static int uboot_nvram_max = UBOOT_ENV_SIZE; ++ ++/* pass envaddr= in bootargs */ ++static int __init envaddr_setup(char *str) ++{ ++ int ret =0; ++ unsigned long ul=0; ++ ++ ret = kstrtoul(str, 16, &ul); ++ ++ if (!ret) { ++ uboot_vars_start = ul; ++ printk("NVRAM: assign 0x%08x\n", uboot_vars_start); ++ } ++ ++ return !ret; ++} ++__setup("envaddr=", envaddr_setup); ++ ++/* ++APIs for access into uboot env vars ++*/ ++ ++int ++nvram_env_init(void) ++{ ++ volatile void *envbuf; ++ char *dp, *sp, *name, *value, *dp_end; ++ char sep = '\0'; ++ int idx=0; ++ ++ ++ printk("NVRAM: map 0x%08x\n", uboot_vars_start); ++ ++ /* map uboot env */ ++ if ((envbuf = (uint8*)ioremap(uboot_vars_start, UBOOT_ENV_SIZE)) == NULL) { ++ printk("%s: ioremap() failed\n", __FUNCTION__); ++ return -ENOMEM; ++ } ++ ++ /* copy memory into buffer */ ++ memcpy((void*)u_boot_env, (void *) envbuf, uboot_nvram_max); ++ ++ /* clear fake entry set */ ++ memset(env_list, 0, sizeof(env_list)); ++ ++ /* load uboot fake nvram buffer */ ++ /* point to first data */ ++ dp = (char*)u_boot_env; ++ /* point to data buffer */ ++ dp += 4; ++ dp_end = (char*)((uint32)u_boot_env+UBOOT_ENV_SIZE); ++ ++ /* point to first data */ ++ do { ++ /* skip leading white space */ ++ while ((*dp == ' ') || (*dp == '\t')) { ++ ++dp; ++ } ++ ++ /* skip comment lines */ ++ if (*dp == '#') { ++ while (*dp && (*dp != sep)) { ++ ++dp; ++ } ++ ++dp; ++ continue; ++ } ++ ++ /* parse name */ ++ for (name = dp; *dp != '=' && *dp && *dp != sep; ++dp) { ++ ; ++ } ++ ++ *dp++ = '\0'; /* terminate name */ ++ ++ /* parse value; deal with escapes */ ++ for (value = sp = dp; *dp && (*dp != sep); ++dp) { ++ if ((*dp == '\\') && *(dp + 1)) { ++ ++dp; ++ } ++ *sp++ = *dp; ++ } ++ *sp++ = '\0'; /* terminate value */ ++ ++dp; ++ ++ /* enter into hash table */ ++ env_list[idx].name = name; ++ env_list[idx].value = value; ++ //printk("entry%d %s=%s\n", idx, name, value); ++ idx++; ++ ++ /* check if table is full */ ++ if (idx >= UBOOT_ENV_MAX_NUM ) { ++ printk("%s: WARNING - UBoot environment table is full\n", __FUNCTION__); ++ break; ++ } ++ /* check if end of table */ ++ } while ((dp < dp_end) && *dp); /* size check needed for text */ ++ ++ u_boot_env_loaded = true; ++ ++ /* unmap uboot env */ ++ iounmap(envbuf); ++ ++ return 0; ++} ++#endif ++ ++int ++nvram_env_gmac_name(int gmac, char *name) ++{ ++ int ret=0; ++ switch (gmac) ++ { ++#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || defined(CONFIG_MACH_SB2) || defined(CONFIG_MACH_GH2)) ++ case 0: ++ strcpy(name, "ethaddr"); ++ break; ++ case 1: ++ sprintf(name, "eth1addr"); ++ break; ++#elif (defined(CONFIG_MACH_HR2) || defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_HR3)) ++ case 0: ++ strcpy(name, "ethaddr"); ++ break; ++#endif ++ default: ++ strcpy(name, "unknown"); ++ ret = -1; ++ break; ++ } ++ return ret; ++ ++} ++ ++char * ++nvram_get(const char *name) ++{ ++ int i, len; ++ nvram_t *tuple; ++ int num_entries; ++ ++ if (!name) { ++ return (char *) 0; ++ } ++ ++ len = strlen(name); ++ if (len == 0) { ++ return (char *) 0; ++ } ++ ++#if defined(CONFIG_MACH_SB2) && defined(CONFIG_MACH_IPROC_EMULATION) ++ static char macAddr[17]; /* = "d4:ae:52:bc:a5:09" */ ++ ++ if (name[0] == 'e' && name[1] == 't' && name[2] == 'h' && name[3] == 'a' && ++ name[4] == 'd' && name[5] == 'd' && name[6] == 'r') ++ { ++ macAddr[0] = 'd'; macAddr[1] = '4'; macAddr[2] = ':'; ++ macAddr[3] = 'a'; macAddr[4] = 'e'; macAddr[5] = ':'; ++ macAddr[6] = '5'; macAddr[7] = '2'; macAddr[8] = ':'; ++ macAddr[9] = 'b'; macAddr[10] = 'c'; macAddr[11] = ':'; ++ macAddr[12] = 'a'; macAddr[13] = '5'; macAddr[14] = ':'; ++ macAddr[15] = '0'; macAddr[16] = '9'; ++ return((char *)macAddr); ++ } /* else if (name[0] == 'e' && name[1] == 't' && name[2] == 'h' && name[3] == '1' && ++ name[4] == 'a' && name[5] == 'd' && name[6] == 'd' && name[7] == 'r') ++ { ++ macAddr[0] = 'd'; macAddr[1] = '5'; macAddr[2] = ':'; ++ macAddr[3] = 'a'; macAddr[4] = 'e'; macAddr[5] = ':'; ++ macAddr[6] = '5'; macAddr[7] = '3'; macAddr[8] = ':'; ++ macAddr[9] = 'b'; macAddr[10] = 'c'; macAddr[11] = ':'; ++ macAddr[12] = 'a'; macAddr[13] = '6'; macAddr[14] = ':'; ++ macAddr[15] = '0'; macAddr[16] = 'a'; ++ return((char *)macAddr); ++ } */ ++#endif ++ ++#ifndef FAKE_NVRAM ++ tuple = &env_list[0]; ++ num_entries = sizeof(env_list)/sizeof(nvram_t); ++ ++ if (!u_boot_env_loaded) { ++ nvram_env_init(); ++ } ++ ++ /* first check the uboot NVRAM variables */ ++ for (i = 0; i < num_entries; i++) { ++ if (tuple->name && (bcmp(tuple->name, name, len) == 0) && (strlen(tuple->name)==len)) { ++ /*printf("%s (NVRAM) %s: %s\n", __FUNCTION__, name, tuple->value);*/ ++ return tuple->value; ++ } ++ tuple++; ++ } ++#endif ++ ++ /* if cant find then check fake table above */ ++ tuple = &fake_nvram[0]; ++ num_entries = fake_nvram_size; ++ for (i = 0; i < num_entries; i++) { ++ if (tuple->name && (bcmp(tuple->name, name, len) == 0) && (strlen(tuple->name)==len)) { ++ /*printf("%s (STUBS) %s: %s\n", __FUNCTION__, name, tuple->value);*/ ++ return tuple->value; ++ } ++ tuple++; ++ } ++ ++ return (char *) 0; ++} ++ ++int ++nvram_set(const char *name, const char *value) ++{ ++ return 0; ++} ++ ++int ++nvram_unset(const char *name) ++{ ++ return 0; ++} ++ ++int ++nvram_commit(void) ++{ ++ return 0; ++} ++ ++int ++nvram_getall(char *buf, int count) ++{ ++ /* add null string as terminator */ ++ if (count < 1) { ++ return BCME_BUFTOOSHORT; ++ } ++ *buf = '\0'; ++ return 0; ++} ++ ++static int __init iproc_nvram_init(void) ++{ ++ nvram_env_init(); ++ return 0; ++} ++subsys_initcall(iproc_nvram_init); +\ No newline at end of file +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/phy542xx.c b/drivers/net/ethernet/broadcom/gmac/src/shared/phy542xx.c +--- a/drivers/net/ethernet/broadcom/gmac/src/shared/phy542xx.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/shared/phy542xx.c 2017-11-09 17:53:44.061289000 +0800 +@@ -0,0 +1,336 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ * ++ * These routines provide access to the external phy ++ * ++ */ ++#include ++#include ++#include "../../../mdio/iproc_mdio.h" ++#include "bcmiproc_phy.h" ++#include "phy542xx.h" ++ ++/* debug/trace */ ++//#define BCMDBG ++//#define BCMDBG_ERR ++#ifdef BCMDBG ++#define NET_ERROR(args) printf args ++#define NET_TRACE(args) printf args ++#elif defined(BCMDBG_ERR) ++#define NET_ERROR(args) printf args ++#define NET_TRACE(args) ++#else ++#define NET_ERROR(args) ++#define NET_TRACE(args) ++#endif /* BCMDBG */ ++#define NET_REG_TRACE(args) ++ ++ ++#ifndef ASSERT ++#define ASSERT(exp) ++#endif ++ ++#define PHY542XX_RDB_REG_RD phy542xx_rdb_reg_read ++#define PHY542XX_RDB_REG_WR phy542xx_rdb_reg_write ++#define PHY542XX_REG_RD phy542xx_reg_read ++#define PHY542XX_REG_WR phy542xx_reg_write ++ ++static int ++phy542xx_rdb_reg_read(u32 phy_addr, u32 reg_addr, u16 *data) ++{ ++ int rv = SOC_E_NONE; ++ ++ /* MDIO write the RDB reg. address to reg.0x1E = */ ++ iproc_mii_write(MII_DEV_EXT, phy_addr, BCM542XX_REG_RDB_ADDR, ++ (0xffff & reg_addr)); ++ ++ /* MDIO read from reg.0x1F to get the RDB register's value as */ ++ iproc_mii_read(MII_DEV_EXT, phy_addr, BCM542XX_REG_RDB_DATA, data); ++ ++ return rv; ++} ++ ++static int ++phy542xx_rdb_reg_write(u32 phy_addr, u32 reg_addr, u16 data) ++{ ++ int rv = SOC_E_NONE; ++ ++ /* MDIO write the RDB reg. address to reg.0x1E = */ ++ iproc_mii_write(MII_DEV_EXT, phy_addr, BCM542XX_REG_RDB_ADDR, ++ (0xffff & reg_addr)); ++ ++ /* MDIO write to reg.0x1F to set the RDB resister's value as */ ++ iproc_mii_write(MII_DEV_EXT, phy_addr, BCM542XX_REG_RDB_DATA, data); ++ ++ return rv; ++} ++ ++int ++phy542xx_reg_read(u32 phy_addr, u32 flags, int reg_addr, u16 *data) ++{ ++ int rv = SOC_E_NONE; ++ u16 val; ++ ++ if (flags & PHY_REG_FLAGS_FIBER) { /* fiber registers */ ++ if (reg_addr <= 0x0f) { ++ if (flags & PHY_REG_FLAGS_1000X) { ++ /* 54220 fiber is controlled by Secondary SerDes */ ++ PHY542XX_RDB_REG_RD(phy_addr, ++ (reg_addr | BCM542XX_REG_RDB_2ND_SERDES_BASE), data); ++ } else { ++ /* Map 1000X page */ ++ PHY542XX_RDB_REG_RD(phy_addr, BCM542XX_REG_RDB_MODE_CTRL, &val); ++ val |= BCM542XX_REG_MODE_CTRL_1000X_EN; ++ PHY542XX_RDB_REG_WR(phy_addr, BCM542XX_REG_RDB_MODE_CTRL, val); ++ ++ /* Read 1000X IEEE register */ ++ iproc_mii_read(MII_DEV_EXT, phy_addr, reg_addr, data); ++ ++ /* Restore IEEE mapping */ ++ PHY542XX_RDB_REG_RD(phy_addr, BCM542XX_REG_RDB_MODE_CTRL, &val); ++ val &= ~BCM542XX_REG_MODE_CTRL_1000X_EN; ++ PHY542XX_RDB_REG_WR(phy_addr, BCM542XX_REG_RDB_MODE_CTRL, val); ++ } ++ } ++ } else if (flags & PHY_REG_FLAGS_RDB) { ++ PHY542XX_RDB_REG_RD(phy_addr, reg_addr, data); ++ } else { ++ iproc_mii_read(MII_DEV_EXT, phy_addr, reg_addr, data); ++ } ++ ++ return rv; ++} ++ ++ ++int ++phy542xx_reg_write(u32 phy_addr, u32 flags, int reg_addr, u16 data) ++{ ++ int rv = SOC_E_NONE; ++ u16 val; ++ ++ if (flags & PHY_REG_FLAGS_FIBER) { /* fiber registers */ ++ if (reg_addr <= 0x0f) { ++ if (flags & PHY_REG_FLAGS_1000X) { ++ /* 54220 fiber is controlled by Secondary SerDes */ ++ PHY542XX_RDB_REG_WR(phy_addr, ++ (reg_addr | BCM542XX_REG_RDB_2ND_SERDES_BASE), data); ++ } else { ++ /* Map 1000X page */ ++ PHY542XX_RDB_REG_RD(phy_addr, BCM542XX_REG_RDB_MODE_CTRL, &val); ++ val |= BCM542XX_REG_MODE_CTRL_1000X_EN; ++ PHY542XX_RDB_REG_WR(phy_addr, BCM542XX_REG_RDB_MODE_CTRL, val); ++ ++ /* Write 1000X IEEE register */ ++ iproc_mii_write(MII_DEV_EXT, phy_addr, reg_addr, data); ++ ++ /* Restore IEEE mapping */ ++ PHY542XX_RDB_REG_RD(phy_addr, BCM542XX_REG_RDB_MODE_CTRL, &val); ++ val &= ~BCM542XX_REG_MODE_CTRL_1000X_EN; ++ PHY542XX_RDB_REG_WR(phy_addr, BCM542XX_REG_RDB_MODE_CTRL, val); ++ } ++ } ++ } else if (flags & PHY_REG_FLAGS_RDB) { ++ PHY542XX_RDB_REG_WR(phy_addr, reg_addr, data); ++ } else { ++ iproc_mii_write(MII_DEV_EXT, phy_addr, reg_addr, data); ++ } ++ ++ return rv; ++} ++ ++static int ++phy542xx_ge_reset(u32 phy_addr) ++{ ++ int rv = SOC_E_NONE; ++ u16 val; ++ ++ NET_TRACE(("%s: phy_addr %d\n", __FUNCTION__, phy_addr)); ++ ++ /* Reset the PHY */ ++ PHY542XX_REG_RD(phy_addr, PHY_REG_FLAGS_NONE, PHY_MII_CTRLr_ADDR, &val); ++ val |= MII_CTRL_RESET; ++ PHY542XX_REG_WR(phy_addr, PHY_REG_FLAGS_NONE, PHY_MII_CTRLr_ADDR, val); ++ ++ SPINWAIT((!PHY542XX_REG_RD(phy_addr, PHY_REG_FLAGS_NONE, PHY_MII_CTRLr_ADDR, &val) && ++ (val & MII_CTRL_RESET)), 100000); ++ ++ /* Check if out of reset */ ++ PHY542XX_REG_RD(phy_addr, PHY_REG_FLAGS_NONE, PHY_MII_CTRLr_ADDR, &val); ++ if (val & MII_CTRL_RESET) { ++ NET_ERROR(("%s reset not complete\n", __FUNCTION__)); ++ rv = SOC_E_TIMEOUT; ++ } else { ++ NET_TRACE(("%s reset complete\n", __FUNCTION__)); ++ } ++ ++ return rv; ++} ++ ++static int ++phy542xx_ge_init(u32 phy_addr) ++{ ++ int rv = SOC_E_NONE; ++ u16 val; ++ ++ /* ++ * Enable direct RDB addressing mode, write to Expansion register ++ * 0x7E = 0x0000 ++ * - MDIO write to reg 0x17 = 0x0F7E ++ * - MDIO write to reg 0x15 = 0x0000 ++ */ ++ PHY542XX_REG_WR(phy_addr, PHY_REG_FLAGS_NONE, ++ BCM542XX_REG_EXP_SEL, BCM542XX_REG_EXP_SELECT_7E); ++ PHY542XX_REG_WR(phy_addr, PHY_REG_FLAGS_NONE, ++ BCM542XX_REG_EXP_DATA, BCM542XX_REG_EXP_RDB_EN); ++ ++ /* Configure auto-detect Medium */ ++ PHY542XX_RDB_REG_RD(phy_addr, MIIM_BCM542xx_RDB_AUTO_DETECT_MEDIUM, &val); ++ val &= ~BCM542XX_REG_MII_AUTO_DET_MASK; ++ /* Enable dual serdes auto-detect medium */ ++ val |= (BCM542XX_REG_MII_AUTO_DET_MED_2ND_SERDES | ++ BCM542XX_REG_MII_FIBER_IN_USE_LED | ++ BCM542XX_REG_MII_FIBER_LED | ++ BCM542XX_REG_MII_FIBER_SD_SYNC); ++ /* Enable auto-detect medium */ ++ val |= BCM542XX_REG_MII_AUTO_DET_MED_EN; ++ /* Fiber selected when both media are active */ ++ val |= (BCM542XX_REG_MII_AUTO_DET_MED_PRI | ++ BCM542XX_REG_MII_AUTO_DET_MED_DEFAULT); ++ PHY542XX_RDB_REG_WR(phy_addr, MIIM_BCM542xx_RDB_AUTO_DETECT_MEDIUM, val); ++ ++ /* Power up primary SerDes, Fiber MII_CONTROL Reg. bit[11]*/ ++ PHY542XX_REG_RD(phy_addr, PHY_REG_FLAGS_PRI_SERDES, PHY_MII_CTRLr_ADDR, &val); ++ val &= ~MII_CTRL_PD; ++ PHY542XX_REG_WR(phy_addr, PHY_REG_FLAGS_PRI_SERDES, PHY_MII_CTRLr_ADDR, val); ++ ++ /* MODE_CONTROL register, DIGX_SHD_1C_1F, RDB_0x21 */ ++ PHY542XX_RDB_REG_RD(phy_addr, BCM542XX_REG_RDB_MODE_CTRL, &val); ++ val &= ~(BCM542XX_REG_MODE_CNTL_MODE_SEL_1 | ++ BCM542XX_REG_MODE_CNTL_MODE_SEL_2); ++ val |= BCM542XX_REG_MODE_SEL_SGMII_2_COPPER; ++ PHY542XX_RDB_REG_WR(phy_addr, BCM542XX_REG_RDB_MODE_CTRL, val); ++ ++ /* COPPER INTERFACE */ ++ PHY542XX_REG_RD(phy_addr, PHY_REG_FLAGS_NONE, PHY_MII_CTRLr_ADDR, &val); ++ val &= ~MII_CTRL_PD; ++ PHY542XX_REG_WR(phy_addr, PHY_REG_FLAGS_NONE, PHY_MII_CTRLr_ADDR, val); ++ ++ PHY542XX_REG_WR(phy_addr, PHY_REG_FLAGS_NONE, MII_CTRL1000, ADVERTISE_1000FULL); ++ PHY542XX_REG_WR(phy_addr, PHY_REG_FLAGS_NONE, PHY_MII_CTRLr_ADDR, ++ (BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_ANENABLE | BMCR_ANRESTART)); ++ ++ /* Enable/disable auto-detection between SGMII-slave and 1000BASE-X */ ++ /* External Serdes Control Reg., DIGX_SHD_1C_14, RDB_0x234 */ ++ PHY542XX_RDB_REG_RD(phy_addr, BCM542XX_REG_RDB_EXT_SERDES_CTRL, &val); ++ val &= ~(BCM542XX_REG_EXT_SERDES_FX_MASK); ++ PHY542XX_RDB_REG_WR(phy_addr, BCM542XX_REG_RDB_EXT_SERDES_CTRL, val); ++ ++ /* SGMII Slave Control Register, DIGX_SHD_1C_15, RDB_0x235 */ ++ PHY542XX_RDB_REG_RD(phy_addr, BCM542XX_REG_RDB_SGMII_SLAVE, &val); ++ val &= ~(BCM542XX_REG_SGMII_SLAVE_AUTO); ++ PHY542XX_RDB_REG_WR(phy_addr, BCM542XX_REG_RDB_SGMII_SLAVE, val); ++ ++ /* FIBER INTERFACE */ ++ /* Remove power down of SerDes */ ++ PHY542XX_REG_RD(phy_addr, PHY_REG_FLAGS_1000X, PHY_MII_CTRLr_ADDR, &val); ++ val &= ~MII_CTRL_PD; ++ PHY542XX_REG_WR(phy_addr, PHY_REG_FLAGS_1000X, PHY_MII_CTRLr_ADDR, val); ++ ++ /* Set the advertisement of serdes */ ++ PHY542XX_REG_RD(phy_addr, PHY_REG_FLAGS_1000X, PHY_MII_ANAr_ADDR, &val); ++ val |= (MII_ANA_FD_1000X | MII_ANA_HD_1000X | ++ MII_ANA_1000X_PAUSE | MII_ANA_1000X_ASYM_PAUSE); ++ PHY542XX_REG_WR(phy_addr, PHY_REG_FLAGS_1000X, PHY_MII_ANAr_ADDR, val); ++ ++ /* Enable auto-detection between SGMII-slave and 1000BASE-X */ ++ /* External Serdes Control Reg., DIGX_SHD_1C_14, RDB_0x234 */ ++ val = (BCM542XX_REG_EXT_SERDES_LED | BCM542XX_REG_EXT_SEL_SYNC_ST | ++ BCM542XX_REG_EXT_SELECT_SD | BCM542XX_REG_EXT_SERDES_SEL); ++ PHY542XX_RDB_REG_WR(phy_addr, BCM542XX_REG_RDB_EXT_SERDES_CTRL, val); ++ ++ /* SGMII Slave Control Register, DIGX_SHD_1C_15, RDB_0x235 */ ++ PHY542XX_RDB_REG_RD(phy_addr, BCM542XX_REG_RDB_SGMII_SLAVE, &val); ++ val &= ~(BCM542XX_REG_SGMII_SLAVE_AUTO); ++ PHY542XX_RDB_REG_WR(phy_addr, BCM542XX_REG_RDB_SGMII_SLAVE, val); ++ ++ /* Miscellanous Control Reg., CORE_SHD18_111, RDB_0x02f */ ++ PHY542XX_RDB_REG_WR(phy_addr, BCM542XX_REG_RDB_MII_MISC_CTRL, 0x2007); ++ ++ /* Second SERDES 100-FX CONTROL Register, RDB_0xb17 */ ++ PHY542XX_RDB_REG_WR(phy_addr, BCM542XX_REG_RDB_2ND_SERDES_MISC_1000X, 0x0); ++ ++ /* Default SerDes config & restart autonegotiation */ ++ PHY542XX_REG_WR(phy_addr, PHY_REG_FLAGS_1000X, PHY_MII_CTRLr_ADDR, ++ (BMCR_FULLDPLX | BMCR_SPEED1000 | BMCR_ANENABLE | BMCR_ANRESTART)); ++ ++ return rv; ++} ++ ++int ++phy542xx_reset_setup(u32 phy_addr) ++{ ++ int rv = SOC_E_NONE; ++ ++ NET_TRACE(("%s enter\n", __FUNCTION__)); ++ ++ rv = phy542xx_ge_reset(phy_addr); ++ ++ if (SOC_SUCCESS(rv)) { ++ rv = phy542xx_ge_init(phy_addr); ++ } ++ ++ return rv; ++} ++ ++int ++phy542xx_init(u32 phy_addr) ++{ ++ u16 phyid0, phyid1; ++ ++ NET_TRACE(("%s: phy_addr %d\n", __FUNCTION__, phy_addr)); ++ ++ PHY542XX_REG_RD(phy_addr, PHY_REG_FLAGS_NONE, PHY_MII_PHY_ID0r_ADDR, &phyid0); ++ PHY542XX_REG_RD(phy_addr, PHY_REG_FLAGS_NONE, PHY_MII_PHY_ID1r_ADDR, &phyid1); ++ ++ printf("%s Phy ChipID: 0x%04x:0x%04x\n", __FUNCTION__, phyid1, phyid0); ++ ++ phy542xx_reset_setup(phy_addr); ++ ++ return 0; ++} ++ ++int ++phy542xx_enable_set(u32 phy_addr, int enable) ++{ ++ u16 val; ++ ++ NET_TRACE(("%s: phy_addr %d\n", __FUNCTION__, phy_addr)); ++ ++ PHY542XX_REG_RD(phy_addr, PHY_REG_FLAGS_PRI_SERDES, PHY_MII_CTRLr_ADDR, &val); ++ if (enable) { ++ val &= ~MII_CTRL_PD; ++ } else { ++ val |= MII_CTRL_PD; ++ } ++ PHY542XX_REG_WR(phy_addr, PHY_REG_FLAGS_PRI_SERDES, PHY_MII_CTRLr_ADDR, val); ++ ++ return SOC_E_NONE; ++} ++ ++int ++phy542xx_force_auto_mdix(u32 phy_addr, int enable) ++{ ++ u16 val; ++ ++ NET_TRACE(("%s: phy_addr %d\n", __FUNCTION__, phy_addr)); ++ ++ PHY542XX_RDB_REG_RD(phy_addr, BCM542XX_REG_RDB_COPPER_MISC_CTRL, &val); ++ if (enable) { ++ val |= BCM542XX_REG_MISC_CTRL_FORCE_AUTO_MDIX; ++ } else { ++ val &= ~BCM542XX_REG_MISC_CTRL_FORCE_AUTO_MDIX; ++ } ++ PHY542XX_RDB_REG_WR(phy_addr, BCM542XX_REG_RDB_COPPER_MISC_CTRL, val); ++ ++ return SOC_E_NONE; ++} +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/sb2_erom.c b/drivers/net/ethernet/broadcom/gmac/src/shared/sb2_erom.c +--- a/drivers/net/ethernet/broadcom/gmac/src/shared/sb2_erom.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/shared/sb2_erom.c 2017-11-09 17:53:44.061307000 +0800 +@@ -0,0 +1,81 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Broadcom Home Networking Division 10/100 Mbit/s Ethernet ++ * Saber2 sudo EROM ++ * ++ */ ++#include ++ ++uint32 sb2_erom[] = { ++ // LOOP 1 : #define MFGID_BRCM 0x4bf /* Manufacturer Ids (mfg) */ ++ // #define CC_CORE_ID 0x800 /* chipcommon core (cid) */ ++ 0x4bf80001, ++ // crev = 0x2a, nsw = 0x0 (mask = 0x0x00f80000), nmw = 0x1 (mask = 0x0007c000), nsp = 0x1 (mask = 0x00003e00), nmp = 0x0 (mask = 0x000001f0) ++ 0x2a004201, ++ // First Slave Address Descriptor should be port 0: the main register space for the core ++ // addr1 = 0x18000000 (mask = 0xfffff000), addrh = 0x0 (AD_AG32 = 0x00000008), sizeh = 0x0, ++ // sz = 0x0 (AD_SZ_MASK = 0x00000030), sizel = 0x00001000 (0x00001000 << (sz >> 4)) ++ 0x18000005, ++ // Now get master wrappers (i = 0) ++ // addr1 = 0x18120000 (AD_ADDR_MASK = 0xfffff000), addrh = 0x0 (AD_AG32 = 0x00000008), sizeh = 0x0, ++ // sz = 0x0 (AD_SZ_MASK = 0x00000030), sizel = 0x00001000 (0x00001000 << (sz >> 4)) ++ 0x181200c5, ++ ++ // LOOP 2 : #define MFGID_BRCM 0x4bf /* Manufacturer Ids (mfg) */ ++ // #define GMAC_CORE_ID 0x82d /* Gigabit MAC core */ ++ // cia = 0x4bf82d01 ++ // cid = 0x82d (cia & CIA_CID_MASK(0x000fff00)) >> CIA_CID_SHIFT(8), mfg = 0x4bf (cia & CIA_MFG_MASK(0xfff00000)) >> CIA_MFG_SHIFT(20) ++ 0x4bf82d01, ++ // cib = 0x04004211 ++ // crev = 0x04 (cib & CIB_REV_MASK(0xff000000)) >> CIB_REV_SHIFT(24), nmw = 0x01 (cib & CIB_NMW_MASK(0x0007c000)) >> CIB_NMW_SHIFT(14) ++ // nsw = 0x0 (cib & CIB_NSW_MASK(0x00f80000)) >> CIB_NSW_SHIFT(19), nmp = 0x01 (cib & CIB_NMP_MASK(0x000001f0)) >> CIB_NMP_SHIFT(4) ++ // nsp = 0x01 (cib & CIB_NSP_MASK(0x00003e00)) >> CIB_NSP_SHIFT(9) ++ 0x04004211, ++ // mpd = 0x00000103 ++ 0x00000103, ++ // First Slave Address Descriptor should be port 0: the main register space for the core ++ // addr1 = 0x18042000 (AD_ADDR_MASK = 0xfffff000), addrh = 0x0 (AD_AG32 = 0x00000008), sizeh = 0x0, ++ // sz = 0x0 (AD_SZ_MASK = 0x00000030), sizel = 0x00001000 (0x00001000 << (sz >> 4)) ++ 0x18042005, ++ // Now get master wrappers (i = 0) ++ // addr1 = 0x18110000 (AD_ADDR_MASK = 0xfffff000), addrh = 0x0 (AD_AG32 = 0x00000008), sizeh = 0x0, ++ // sz = 0x0 (AD_SZ_MASK = 0x00000030), sizel = 0x00001000 (0x00001000 << (sz >> 4)) ++ 0x181100c5, ++ ++ // LOOP 3 : #define MFGID_BRCM 0x4bf /* Manufacturer Ids (mfg) */ ++ // #define GMAC_CORE_ID 0x82d /* Gigabit MAC core */ ++ // cia = 0x4bf82d01 ++ // cid = 0x82d (cia & CIA_CID_MASK(0x000fff00)) >> CIA_CID_SHIFT(8), mfg = 0x4bf (cia & CIA_MFG_MASK(0xfff00000)) >> CIA_MFG_SHIFT(20) ++ 0x4bf82d01, ++ // cib = 0x04004211 ++ // crev = 0x04 (cib & CIB_REV_MASK(0xff000000)) >> CIB_REV_SHIFT(24), nmw = 0x01 (cib & CIB_NMW_MASK(0x0007c000)) >> CIB_NMW_SHIFT(14) ++ // nsw = 0x0 (cib & CIB_NSW_MASK(0x00f80000)) >> CIB_NSW_SHIFT(19), nmp = 0x01 (cib & CIB_NMP_MASK(0x000001f0)) >> CIB_NMP_SHIFT(4) ++ // nsp = 0x01 (cib & CIB_NSP_MASK(0x00003e00)) >> CIB_NSP_SHIFT(9) ++ 0x04004211, ++ // mpd = 0x00000203 ++ 0x00000203, ++ // First Slave Address Descriptor should be port 0: the main register space for the core ++ // addr1 = 0x1804a000 (AD_ADDR_MASK = 0xfffff000), addrh = 0x0 (AD_AG32 = 0x00000008), sizeh = 0x0, ++ // sz = 0x0 (AD_SZ_MASK = 0x00000030), sizel = 0x00001000 (0x00001000 << (sz >> 4)) ++ 0x1804a005, ++ // Now get master wrappers (i = 0) ++ // addr1 = 0x18110000 (AD_ADDR_MASK = 0xfffff000), addrh = 0x0 (AD_AG32 = 0x00000008), sizeh = 0x0, ++ // sz = 0x0 (AD_SZ_MASK = 0x00000030), sizel = 0x00001000 (0x00001000 << (sz >> 4)) ++ 0x181110c5, ++ ++ // END of parse loop 0x0f = (ER_END(0x0e) | ER_VALID(0x01)) ++ 0x0000000f ++}; +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/sb2_erom.h b/drivers/net/ethernet/broadcom/gmac/src/shared/sb2_erom.h +--- a/drivers/net/ethernet/broadcom/gmac/src/shared/sb2_erom.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/shared/sb2_erom.h 2017-11-09 17:53:44.062302000 +0800 +@@ -0,0 +1,26 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Broadcom Home Networking Division 10/100 Mbit/s Ethernet ++ * Saber2 sudo EROM ++ * ++ */ ++ ++#ifndef _sb2_erom_h_ ++#define _sb2_erom_h_ ++ ++extern uint32 sb2_erom[]; ++ ++#endif /* _sb2_erom_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/sgmiiplus2_serdes.c b/drivers/net/ethernet/broadcom/gmac/src/shared/sgmiiplus2_serdes.c +--- a/drivers/net/ethernet/broadcom/gmac/src/shared/sgmiiplus2_serdes.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/shared/sgmiiplus2_serdes.c 2017-11-09 17:53:44.063293000 +0800 +@@ -0,0 +1,102 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ * ++ * These routines provide access to the serdes ++ * ++ */ ++ ++/* ---- Include Files ---------------------------------------------------- */ ++#include ++#include ++#include "bcmiproc_serdes.h" ++#include "bcmiproc_serdes_def.h" ++#include "../../../mdio/iproc_mdio.h" ++ ++/* ---- External Variable Declarations ----------------------------------- */ ++/* ---- External Function Prototypes ------------------------------------- */ ++/* ---- Public Variables ------------------------------------------------- */ ++/* ---- Private Constants and Types -------------------------------------- */ ++/* ---- Private Variables ------------------------------------------------ */ ++ ++/* debug/trace */ ++//#define BCMDBG ++//#define BCMDBG_ERR ++#ifdef BCMDBG ++#define NET_ERROR(args) printf args ++#define NET_TRACE(args) printf args ++#elif defined(BCMDBG_ERR) ++#define NET_ERROR(args) printf args ++#define NET_TRACE(args) ++#else ++#define NET_ERROR(args) ++#define NET_TRACE(args) ++#endif /* BCMDBG */ ++#define NET_REG_TRACE(args) ++ ++#ifndef ASSERT ++#define ASSERT(exp) ++#endif ++ ++void ++sgmiiplus2_serdes_reset(uint eth_num, uint phyaddr) ++{ ++ uint16 ctrl; ++ ++ ASSERT(phyaddr < MAXEPHY); ++ ++ if (phyaddr == EPHY_NOREG) ++ return; ++ ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x1f, 0x0); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0, 0x8000); ++ ++ udelay(100); ++ ++ iproc_mii_read(MII_DEV_LOCAL, phyaddr, 0x0, &ctrl); ++ if (ctrl & 0x8000) ++ NET_ERROR(("et%d: %s serdes reset not complete\n", eth_num, __FUNCTION__)); ++ ++} ++ ++int ++sgmiiplus2_serdes_init(uint eth_num, uint phyaddr) ++{ ++ u16 id1, id2; ++ ++ iproc_mii_read(MII_DEV_LOCAL, phyaddr, 0x0002, &id1); ++ iproc_mii_read(MII_DEV_LOCAL, phyaddr, 0x0003, &id2); ++ printf("Internal phyaddr %d: Get PHY ID0:%.4x, ID1:%.4x\n", phyaddr, id1, id2); ++ ++ /* Disable PLL */ ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0xffd0); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001e, 0x0000); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8000); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x062f); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001e, 0x0000); ++ ++ /* Disable lmtcal (broadcast to all lanes) */ ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0xffd0); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001e, 0x001f); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8480); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0012, 0x83f8); ++ ++ /* Auto negotiation 10/100/1G - SGMII Slave (broadcast to all lanes) */ ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8300); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x0100); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8340); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001a, 0x0003); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x0000); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0000, 0x1140); ++ ++ /* Change PLL calibration threshold to 0xc */ ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0xffd0); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001e, 0x0000); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8180); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0011, 0x0600); ++ ++ /* Enable PLL */ ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8000); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x262f); ++ ++ return 0; ++} +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/siutils.c b/drivers/net/ethernet/broadcom/gmac/src/shared/siutils.c +--- a/drivers/net/ethernet/broadcom/gmac/src/shared/siutils.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/shared/siutils.c 2017-11-09 17:53:44.065294000 +0800 +@@ -0,0 +1,1409 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Misc utility routines for accessing chip-specific features ++ * of the SiliconBackplane-based Broadcom chips. ++ * ++ * $Id: siutils.c 328955 2012-04-23 09:06:12Z $ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "siutils_priv.h" ++ ++/* local prototypes */ ++static si_info_t *si_doattach(si_info_t *sii, uint devid, osl_t *osh, void *regs, ++ uint bustype, void *sdh, char **vars, uint *varsz); ++static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin, ++ uint *origidx, void *regs); ++ ++static void si_nvram_process(si_info_t *sii, char *pvars); ++/* dev path concatenation util */ ++static char *si_devpathvar(si_t *sih, char *var, int len, const char *name); ++static bool _si_clkctl_cc(si_info_t *sii, uint mode); ++ ++/* global variable to indicate reservation/release of gpio's */ ++static uint32 si_gpioreservation = 0; ++ ++/* global flag to prevent shared resources from being initialized multiple times in si_attach() */ ++ ++/* ++ * Allocate a si handle. ++ * devid - pci device id (used to determine chip#) ++ * osh - opaque OS handle ++ * regs - virtual address of initial core registers ++ * bustype - pci/pcmcia/sb/sdio/etc ++ * vars - pointer to a pointer area for "environment" variables ++ * varsz - pointer to int to return the size of the vars ++ */ ++si_t * ++BCMATTACHFN(si_attach)(uint devid, osl_t *osh, void *regs, ++ uint bustype, void *sdh, char **vars, uint *varsz) ++{ ++ si_info_t *sii; ++ si_t *sih; ++ ++ /* alloc si_info_t */ ++ if ((sii = MALLOC(osh, sizeof (si_info_t))) == NULL) { ++ SI_ERROR(("si_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh))); ++ return (NULL); ++ } ++ ++ if (si_doattach(sii, devid, osh, regs, bustype, sdh, vars, varsz) == NULL) { ++ MFREE(osh, sii, sizeof(si_info_t)); ++ SI_ERROR(("%s si_doattach() failed\n", __FUNCTION__)); ++ return (NULL); ++ } ++ sii->vars = vars ? *vars : NULL; ++ sii->varsz = varsz ? *varsz : 0; ++ ++ sih = (si_t*)sii; ++ printk("%s socitype(0x%x) chip(0x%x) chiprev(0x%x) chippkg(0x%x)\n", ++ __FUNCTION__, sih->socitype, sih->chip, sih->chiprev, sih->chippkg); ++ ++ return (si_t *)sii; ++} ++ ++static bool ++BCMATTACHFN(si_buscore_setup)(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin, ++ uint *origidx, void *regs) ++{ ++ bool pci, pcie; ++ uint i; ++ uint pciidx, pcieidx, pcirev, pcierev; ++ ++ cc = si_setcoreidx(&sii->pub, SI_CC_IDX); ++ ASSERT((uintptr)cc); ++ ++ /* get chipcommon rev */ ++ sii->pub.ccrev = (int)si_corerev(&sii->pub); ++ ++ /* get chipcommon chipstatus */ ++ if (sii->pub.ccrev >= 11) { ++ sii->pub.chipst = R_REG(sii->osh, &cc->chipstatus); ++ } ++ ++ /* get chipcommon capabilites */ ++ sii->pub.cccaps = R_REG(sii->osh, &cc->capabilities); ++ /* get chipcommon extended capabilities */ ++ if (sii->pub.ccrev >= 35) { ++ sii->pub.cccaps_ext = R_REG(sii->osh, &cc->capabilities_ext); ++ } ++ ++ /* get pmu rev and caps */ ++ if (sii->pub.cccaps & CC_CAP_PMU) { ++ sii->pub.pmucaps = R_REG(sii->osh, &cc->pmucapabilities); ++ sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK; ++ } ++ ++ SI_MSG(("Chipc: rev %d, caps 0x%x, chipst 0x%x pmurev %d, pmucaps 0x%x\n", ++ sii->pub.ccrev, sii->pub.cccaps, sii->pub.chipst, sii->pub.pmurev, ++ sii->pub.pmucaps)); ++ ++ /* figure out bus/orignal core idx */ ++ sii->pub.buscoretype = NODEV_CORE_ID; ++ sii->pub.buscorerev = (uint)NOREV; ++ sii->pub.buscoreidx = BADIDX; ++ ++ pci = pcie = FALSE; ++ pcirev = pcierev = (uint)NOREV; ++ pciidx = pcieidx = BADIDX; ++ ++ for (i = 0; i < sii->numcores; i++) { ++ uint cid, crev; ++ ++ si_setcoreidx(&sii->pub, i); ++ cid = si_coreid(&sii->pub); ++ crev = si_corerev(&sii->pub); ++ ++ /* Display cores found */ ++ SI_VMSG(("CORE[%d]: id 0x%x rev %d base 0x%x regs 0x%p\n", ++ i, cid, crev, sii->coresba[i], sii->regs[i])); ++ ++ /* find the core idx before entering this func. */ ++ if ((savewin && (savewin == sii->coresba[i])) || ++ (regs == sii->regs[i])) { ++ *origidx = i; ++ } ++ } ++ ++ SI_VMSG(("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx, sii->pub.buscoretype, ++ sii->pub.buscorerev)); ++ ++ /* return to the original core */ ++ si_setcoreidx(&sii->pub, *origidx); ++ ++ return TRUE; ++} ++ ++static void ++BCMATTACHFN(si_nvram_process)(si_info_t *sii, char *pvars) ++{ ++ /* get boardtype and boardrev */ ++ switch (BUSTYPE(sii->pub.bustype)) { ++ case SI_BUS: ++ sii->pub.boardvendor = VENDOR_BROADCOM; ++ if (pvars == NULL || ((sii->pub.boardtype = getintvar(pvars, "prodid")) == 0)) { ++ if ((sii->pub.boardtype = getintvar(NULL, "boardtype")) == 0) { ++ sii->pub.boardtype = 0xffff; ++ } ++ } ++ break; ++ } ++ ++ if (sii->pub.boardtype == 0) { ++ SI_ERROR(("si_doattach: unknown board type\n")); ++ ASSERT(sii->pub.boardtype); ++ } ++ ++ sii->pub.boardrev = getintvar(pvars, "boardrev"); ++ sii->pub.boardflags = getintvar(pvars, "boardflags"); ++} ++ ++static si_info_t * ++BCMATTACHFN(si_doattach)(si_info_t *sii, uint devid, osl_t *osh, void *regs, ++ uint bustype, void *sdh, char **vars, uint *varsz) ++{ ++ struct si_pub *sih = &sii->pub; ++ uint32 w, savewin; ++ chipcregs_t *cc; ++ char *pvars = NULL; ++ uint origidx; ++ ASSERT(GOODREGS(regs)); ++ ++ bzero((uchar*)sii, sizeof(si_info_t)); ++ ++ savewin = 0; ++ sih->buscoreidx = BADIDX; ++ sii->curmap = regs; ++ sii->sdh = sdh; ++ sii->osh = osh; ++ ++ /* find Chipcommon address */ ++ cc = (chipcregs_t *)REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE); ++ ++ sih->bustype = bustype; ++ if (bustype != BUSTYPE(bustype)) { ++ SI_ERROR(("si_doattach: bus type %d does not match configured bus type %d\n", ++ bustype, BUSTYPE(bustype))); ++ return NULL; ++ } ++ ++ /* ChipID recognition. ++ * We assume we can read chipid at offset 0 from the regs arg. ++ * If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon), ++ * some way of recognizing them needs to be added here. ++ */ ++ if (!cc) { ++ SI_ERROR(("%s: chipcommon register space is null \n", __FUNCTION__)); ++ return NULL; ++ } ++ w = R_REG(osh, &cc->chipid); ++ printk("%s chipid: 0x%x\n", __FUNCTION__, w); ++#if defined(CONFIG_MACH_IPROC_P7) ++ sih->socitype = SOCI_AI; ++ /* get chip id rev & pkg */ ++ sih->chip = w & 0xfffff; ++ sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT; ++ w = R_REG(osh, &cc->capabilities); ++ sih->chiprev = w & 0xff; ++#else ++ sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT; ++ /* Might as wll fill in chip id rev & pkg */ ++ sih->chip = w & CID_ID_MASK; ++ sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT; ++ sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT; ++ /* printk("%s chip: 0x%x; chiprev: 0x%x; chippkg: 0x%x\n", __FUNCTION__, sih->chip, sih->chiprev, sih->chippkg); */ ++#endif /* CONFIG_MACH_IPROC_P7 */ ++ ++ sih->issim = IS_SIM(sih->chippkg); ++ ++ /* scan for cores */ ++ if (CHIPTYPE(sih->socitype) == SOCI_SB) { ++ SI_MSG(("Found chip type SB (0x%08x)\n", w)); ++ sb_scan(sih, regs, devid); ++ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { ++ SI_MSG(("Found chip type %s (0x%08x)\n", (CHIPTYPE(sih->socitype) == SOCI_AI) ? "AI" : "NS", w)); ++ ai_scan(sih, (void *)(uintptr)cc, devid); ++ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { ++ SI_MSG(("Found chip type UBUS (0x%08x), chip id = 0x%4x\n", w, sih->chip)); ++ ub_scan(sih, (void *)(uintptr)cc, devid); ++ } else { ++ SI_ERROR(("Found chip of unknown type (0x%08x)\n", w)); ++ return NULL; ++ } ++ ++ /* no cores found, bail out */ ++ if (sii->numcores == 0) { ++ SI_ERROR(("si_doattach: could not find any cores\n")); ++ return NULL; ++ } ++ /* bus/core/clk setup */ ++ origidx = SI_CC_IDX; ++ if (!si_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) { ++ SI_ERROR(("si_doattach: si_buscore_setup failed\n")); ++ goto exit; ++ } ++ ++ spin_lock_init(&sih->sih_lock); ++ ++ /* Init nvram from flash if it exists */ ++ nvram_init((void *)sih); ++ ++ pvars = vars ? *vars : NULL; ++ si_nvram_process(sii, pvars); ++ ++ /* bootloader should retain default pulls */ ++#ifndef BCM_BOOTLOADER ++ if (sih->ccrev >= 20) { ++ uint32 gpiopullup = 0, gpiopulldown = 0; ++ cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); ++ ASSERT(cc != NULL); ++ ++ W_REG(osh, &cc->gpiopullup, gpiopullup); ++ W_REG(osh, &cc->gpiopulldown, gpiopulldown); ++ si_setcoreidx(sih, origidx); ++ } ++#endif /* !BCM_BOOTLOADER */ ++ ++ ++ /* setup the GPIO based LED powersave register */ ++ if (sih->ccrev >= 16) { ++ if ((w = getintvar(pvars, "leddc")) == 0) { ++ w = DEFAULT_GPIOTIMERVAL; ++ } ++ si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, gpiotimerval), ~0, w); ++ } ++ ++#if !defined(_CFE_) || defined(CFG_WL) ++ /* enable GPIO interrupts when clocks are off */ ++ if (sih->ccrev >= 21) { ++ uint32 corecontrol; ++ corecontrol = si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, corecontrol), ++ 0, 0); ++ corecontrol |= CC_ASYNCGPIO; ++ si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, corecontrol), ++ corecontrol, corecontrol); ++ } ++#endif /* !_CFE_ || CFG_WL */ ++ ++ return (sii); ++exit: ++ return NULL; ++} ++ ++/* may be called with core in reset */ ++void ++BCMATTACHFN(si_detach)(si_t *sih) ++{ ++ si_info_t *sii; ++ uint idx; ++ ++ sii = SI_INFO(sih); ++ if (sii == NULL) { ++ return; ++ } ++ ++ if (BUSTYPE(sih->bustype) == SI_BUS) { ++ for (idx = 0; idx < SI_MAXCORES; idx++) { ++ if (sii->regs[idx]) { ++ REG_UNMAP(sii->regs[idx]); ++ sii->regs[idx] = NULL; ++ } ++ } ++ } ++ ++ MFREE(sii->osh, sii, sizeof(si_info_t)); ++} ++ ++void * ++si_osh(si_t *sih) ++{ ++ si_info_t *sii; ++ ++ sii = SI_INFO(sih); ++ return sii->osh; ++} ++ ++void ++si_setosh(si_t *sih, osl_t *osh) ++{ ++ si_info_t *sii; ++ ++ sii = SI_INFO(sih); ++ if (sii->osh != NULL) { ++ SI_ERROR(("osh is already set....\n")); ++ ASSERT(!sii->osh); ++ } ++ sii->osh = osh; ++} ++ ++uint ++si_intflag(si_t *sih) ++{ ++ si_info_t *sii = SI_INFO(sih); ++ ++ if (CHIPTYPE(sih->socitype) == SOCI_SB) { ++ return sb_intflag(sih); ++ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { ++ return R_REG(sii->osh, ((uint32 *)(uintptr) ++ (sii->oob_router + OOB_STATUSA))); ++ } ++ ++ ASSERT(0); ++ return 0; ++} ++ ++uint ++si_flag(si_t *sih) ++{ ++ if (CHIPTYPE(sih->socitype) == SOCI_SB) { ++ return sb_flag(sih); ++ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { ++ return ai_flag(sih); ++ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { ++ return ub_flag(sih); ++ } ++ ++ ASSERT(0); ++ return 0; ++} ++ ++void ++si_setint(si_t *sih, int siflag) ++{ ++ if (CHIPTYPE(sih->socitype) == SOCI_SB) { ++ sb_setint(sih, siflag); ++ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { ++ ai_setint(sih, siflag); ++ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { ++ ub_setint(sih, siflag); ++ } else { ++ ASSERT(0); ++ } ++} ++ ++uint ++si_coreid(si_t *sih) ++{ ++ si_info_t *sii; ++ ++ sii = SI_INFO(sih); ++ return sii->coreid[sii->curidx]; ++} ++ ++uint ++si_coreidx(si_t *sih) ++{ ++ si_info_t *sii; ++ ++ sii = SI_INFO(sih); ++ return sii->curidx; ++} ++ ++/* return the core-type instantiation # of the current core */ ++uint ++si_coreunit(si_t *sih) ++{ ++ si_info_t *sii; ++ uint idx; ++ uint coreid; ++ uint coreunit; ++ uint i; ++ ++ sii = SI_INFO(sih); ++ coreunit = 0; ++ ++ idx = sii->curidx; ++ ++ ASSERT(GOODREGS(sii->curmap)); ++ coreid = si_coreid(sih); ++ ++ /* count the cores of our type */ ++ for (i = 0; i < idx; i++) { ++ if (sii->coreid[i] == coreid) { ++ coreunit++; ++ } ++ } ++ ++ return (coreunit); ++} ++ ++uint ++si_corevendor(si_t *sih) ++{ ++ if (CHIPTYPE(sih->socitype) == SOCI_SB) { ++ return sb_corevendor(sih); ++ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { ++ return ai_corevendor(sih); ++ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { ++ return ub_corevendor(sih); ++ } ++ ++ ASSERT(0); ++ return 0; ++} ++ ++bool ++si_backplane64(si_t *sih) ++{ ++ return ((sih->cccaps & CC_CAP_BKPLN64) != 0); ++} ++ ++uint ++si_corerev(si_t *sih) ++{ ++ if (CHIPTYPE(sih->socitype) == SOCI_SB) { ++ return sb_corerev(sih); ++ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { ++ return ai_corerev(sih); ++ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { ++ return ub_corerev(sih); ++ } ++ ++ ASSERT(0); ++ return 0; ++} ++ ++/* return index of coreid or BADIDX if not found */ ++uint ++si_findcoreidx(si_t *sih, uint coreid, uint coreunit) ++{ ++ si_info_t *sii; ++ uint found; ++ uint i; ++ ++ sii = SI_INFO(sih); ++ ++ found = 0; ++ ++ for (i = 0; i < sii->numcores; i++) { ++ if (sii->coreid[i] == coreid) { ++ if (found == coreunit) ++ return (i); ++ found++; ++ } ++ } ++ ++ return (BADIDX); ++} ++ ++/* return list of found cores */ ++uint ++si_corelist(si_t *sih, uint coreid[]) ++{ ++ si_info_t *sii; ++ ++ sii = SI_INFO(sih); ++ ++ bcopy((uchar*)sii->coreid, (uchar*)coreid, (sii->numcores * sizeof(uint))); ++ return (sii->numcores); ++} ++ ++/* return current register mapping */ ++void * ++si_coreregs(si_t *sih) ++{ ++ si_info_t *sii; ++ ++ sii = SI_INFO(sih); ++ ASSERT(GOODREGS(sii->curmap)); ++ ++ return (sii->curmap); ++} ++ ++/* ++ * This function changes logical "focus" to the indicated core; ++ * must be called with interrupts off. ++ * Moreover, callers should keep interrupts off during switching out of and back to d11 core ++ */ ++void * ++si_setcore(si_t *sih, uint coreid, uint coreunit) ++{ ++ uint idx; ++ ++ idx = si_findcoreidx(sih, coreid, coreunit); ++ if (!GOODIDX(idx)) { ++ return (NULL); ++ } ++ ++ if (CHIPTYPE(sih->socitype) == SOCI_SB) { ++ return sb_setcoreidx(sih, idx); ++ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { ++ return ai_setcoreidx(sih, idx); ++ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { ++ return ub_setcoreidx(sih, idx); ++ } ++ ++ ASSERT(0); ++ return NULL; ++} ++ ++void * ++si_setcoreidx(si_t *sih, uint coreidx) ++{ ++ if (CHIPTYPE(sih->socitype) == SOCI_SB) { ++ return sb_setcoreidx(sih, coreidx); ++ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { ++ return ai_setcoreidx(sih, coreidx); ++ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { ++ return ub_setcoreidx(sih, coreidx); ++ } ++ ++ ASSERT(0); ++ return 0; ++} ++ ++/* Turn off interrupt as required by sb_setcore, before switch core */ ++void * ++si_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val) ++{ ++ void *cc; ++ si_info_t *sii; ++ ++ sii = SI_INFO(sih); ++ ++ if (SI_FAST(sii)) { ++ /* Overloading the origidx variable to remember the coreid, ++ * this works because the core ids cannot be confused with ++ * core indices. ++ */ ++ *origidx = coreid; ++ if (coreid == CC_CORE_ID) { ++ return (void *)CCREGS_FAST(sii); ++ } else if (coreid == sih->buscoretype) { ++ return (void *)PCIEREGS(sii); ++ } ++ } ++ INTR_OFF(sii, *intr_val); ++ *origidx = sii->curidx; ++ cc = si_setcore(sih, coreid, 0); ++ ASSERT(cc != NULL); ++ ++ return cc; ++} ++ ++/* restore coreidx and restore interrupt */ ++void ++si_restore_core(si_t *sih, uint coreid, uint intr_val) ++{ ++ si_info_t *sii; ++ ++ sii = SI_INFO(sih); ++ if (SI_FAST(sii) && ((coreid == CC_CORE_ID) || (coreid == sih->buscoretype))) { ++ return; ++ } ++ ++ si_setcoreidx(sih, coreid); ++ INTR_RESTORE(sii, intr_val); ++} ++ ++int ++si_numaddrspaces(si_t *sih) ++{ ++ if (CHIPTYPE(sih->socitype) == SOCI_SB) { ++ return sb_numaddrspaces(sih); ++ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { ++ return ai_numaddrspaces(sih); ++ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { ++ return ub_numaddrspaces(sih); ++ } ++ ++ ASSERT(0); ++ return 0; ++} ++ ++uint32 ++si_addrspace(si_t *sih, uint asidx) ++{ ++ if (CHIPTYPE(sih->socitype) == SOCI_SB) { ++ return sb_addrspace(sih, asidx); ++ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { ++ return ai_addrspace(sih, asidx); ++ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { ++ return ub_addrspace(sih, asidx); ++ } ++ ++ ASSERT(0); ++ return 0; ++} ++ ++uint32 ++si_addrspacesize(si_t *sih, uint asidx) ++{ ++ if (CHIPTYPE(sih->socitype) == SOCI_SB) { ++ return sb_addrspacesize(sih, asidx); ++ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { ++ return ai_addrspacesize(sih, asidx); ++ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { ++ return ub_addrspacesize(sih, asidx); ++ } ++ ++ ASSERT(0); ++ return 0; ++} ++ ++void ++si_coreaddrspaceX(si_t *sih, uint asidx, uint32 *addr, uint32 *size) ++{ ++ /* Only supported for SOCI_AI */ ++ if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { ++ ai_coreaddrspaceX(sih, asidx, addr, size); ++ } else { ++ *size = 0; ++ } ++} ++ ++uint32 ++si_core_cflags(si_t *sih, uint32 mask, uint32 val) ++{ ++ if (CHIPTYPE(sih->socitype) == SOCI_SB) { ++ return sb_core_cflags(sih, mask, val); ++ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { ++ return ai_core_cflags(sih, mask, val); ++ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { ++ return ub_core_cflags(sih, mask, val); ++ } ++ ++ ASSERT(0); ++ return 0; ++} ++ ++void ++si_core_cflags_wo(si_t *sih, uint32 mask, uint32 val) ++{ ++ if (CHIPTYPE(sih->socitype) == SOCI_SB) { ++ sb_core_cflags_wo(sih, mask, val); ++ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { ++ ai_core_cflags_wo(sih, mask, val); ++ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { ++ ub_core_cflags_wo(sih, mask, val); ++ } else { ++ ASSERT(0); ++ } ++} ++ ++uint32 ++si_core_sflags(si_t *sih, uint32 mask, uint32 val) ++{ ++ if (CHIPTYPE(sih->socitype) == SOCI_SB) { ++ return sb_core_sflags(sih, mask, val); ++ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { ++ return ai_core_sflags(sih, mask, val); ++ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { ++ return ub_core_sflags(sih, mask, val); ++ } ++ ++ ASSERT(0); ++ return 0; ++} ++ ++bool ++si_iscoreup(si_t *sih) ++{ ++ if (CHIPTYPE(sih->socitype) == SOCI_SB) { ++ return sb_iscoreup(sih); ++ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { ++ return ai_iscoreup(sih); ++ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { ++ return ub_iscoreup(sih); ++ } ++ ++ ASSERT(0); ++ return FALSE; ++} ++ ++uint ++si_wrapperreg(si_t *sih, uint32 offset, uint32 mask, uint32 val) ++{ ++ /* only for AI back plane chips */ ++ if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { ++ return (ai_wrap_reg(sih, offset, mask, val)); ++ } ++ return 0; ++} ++ ++uint ++si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) ++{ ++ if (CHIPTYPE(sih->socitype) == SOCI_SB) { ++ return sb_corereg(sih, coreidx, regoff, mask, val); ++ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { ++ return ai_corereg(sih, coreidx, regoff, mask, val); ++ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { ++ return ub_corereg(sih, coreidx, regoff, mask, val); ++ } ++ ++ ASSERT(0); ++ return 0; ++} ++ ++void ++si_core_disable(si_t *sih, uint32 bits) ++{ ++ if (CHIPTYPE(sih->socitype) == SOCI_SB) { ++ sb_core_disable(sih, bits); ++ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { ++ ai_core_disable(sih, bits); ++ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { ++ ub_core_disable(sih, bits); ++ } ++} ++ ++void ++si_core_reset(si_t *sih, uint32 bits, uint32 resetbits) ++{ ++ if (CHIPTYPE(sih->socitype) == SOCI_SB) { ++ sb_core_reset(sih, bits, resetbits); ++ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { ++ ai_core_reset(sih, bits, resetbits); ++ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { ++ ub_core_reset(sih, bits, resetbits); ++ } ++} ++ ++/* Run bist on current core. Caller needs to take care of core-specific bist hazards */ ++int ++si_corebist(si_t *sih) ++{ ++ uint32 cflags; ++ int result = 0; ++ ++ /* Read core control flags */ ++ cflags = si_core_cflags(sih, 0, 0); ++ ++ /* Set bist & fgc */ ++ si_core_cflags(sih, ~0, (SICF_BIST_EN | SICF_FGC)); ++ ++ /* Wait for bist done */ ++ SPINWAIT(((si_core_sflags(sih, 0, 0) & SISF_BIST_DONE) == 0), 100000); ++ ++ if (si_core_sflags(sih, 0, 0) & SISF_BIST_ERROR) { ++ result = BCME_ERROR; ++ } ++ ++ /* Reset core control flags */ ++ si_core_cflags(sih, 0xffff, cflags); ++ ++ return result; ++} ++ ++static uint32 ++BCMINITFN(factor6)(uint32 x) ++{ ++ switch (x) { ++ case CC_F6_2: return 2; ++ case CC_F6_3: return 3; ++ case CC_F6_4: return 4; ++ case CC_F6_5: return 5; ++ case CC_F6_6: return 6; ++ case CC_F6_7: return 7; ++ default: return 0; ++ } ++} ++ ++/* calculate the speed the SI would run at given a set of clockcontrol values */ ++uint32 ++BCMINITFN(si_clock_rate)(uint32 pll_type, uint32 n, uint32 m) ++{ ++ uint32 n1, n2, clock, m1, m2, m3, mc; ++ ++ n1 = n & CN_N1_MASK; ++ n2 = (n & CN_N2_MASK) >> CN_N2_SHIFT; ++ ++ if (pll_type == PLL_TYPE6) { ++ if (m & CC_T6_MMASK) { ++ return CC_T6_M1; ++ } else { ++ return CC_T6_M0; ++ } ++ } else if ((pll_type == PLL_TYPE1) || ++ (pll_type == PLL_TYPE3) || ++ (pll_type == PLL_TYPE4) || ++ (pll_type == PLL_TYPE7)) { ++ n1 = factor6(n1); ++ n2 += CC_F5_BIAS; ++ } else if (pll_type == PLL_TYPE2) { ++ n1 += CC_T2_BIAS; ++ n2 += CC_T2_BIAS; ++ ASSERT((n1 >= 2) && (n1 <= 7)); ++ ASSERT((n2 >= 5) && (n2 <= 23)); ++ } else if (pll_type == PLL_TYPE5) { ++ return (100000000); ++ } else { ++ ASSERT(0); ++ } ++ ++ /* PLL types 3 and 7 use BASE2 (25Mhz) */ ++ if ((pll_type == PLL_TYPE3) || ++ (pll_type == PLL_TYPE7)) { ++ clock = CC_CLOCK_BASE2 * n1 * n2; ++ } else { ++ clock = CC_CLOCK_BASE1 * n1 * n2; ++ } ++ ++ if (clock == 0) { ++ return 0; ++ } ++ ++ m1 = m & CC_M1_MASK; ++ m2 = (m & CC_M2_MASK) >> CC_M2_SHIFT; ++ m3 = (m & CC_M3_MASK) >> CC_M3_SHIFT; ++ mc = (m & CC_MC_MASK) >> CC_MC_SHIFT; ++ ++ if ((pll_type == PLL_TYPE1) || ++ (pll_type == PLL_TYPE3) || ++ (pll_type == PLL_TYPE4) || ++ (pll_type == PLL_TYPE7)) { ++ m1 = factor6(m1); ++ if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE3)) { ++ m2 += CC_F5_BIAS; ++ } else { ++ m2 = factor6(m2); ++ } ++ m3 = factor6(m3); ++ ++ switch (mc) { ++ case CC_MC_BYPASS: return (clock); ++ case CC_MC_M1: return (clock / m1); ++ case CC_MC_M1M2: return (clock / (m1 * m2)); ++ case CC_MC_M1M2M3: return (clock / (m1 * m2 * m3)); ++ case CC_MC_M1M3: return (clock / (m1 * m3)); ++ default: return (0); ++ } ++ } else { ++ ASSERT(pll_type == PLL_TYPE2); ++ ++ m1 += CC_T2_BIAS; ++ m2 += CC_T2M2_BIAS; ++ m3 += CC_T2_BIAS; ++ ASSERT((m1 >= 2) && (m1 <= 7)); ++ ASSERT((m2 >= 3) && (m2 <= 10)); ++ ASSERT((m3 >= 2) && (m3 <= 7)); ++ ++ if ((mc & CC_T2MC_M1BYP) == 0) { ++ clock /= m1; ++ } ++ if ((mc & CC_T2MC_M2BYP) == 0) { ++ clock /= m2; ++ } ++ if ((mc & CC_T2MC_M3BYP) == 0) { ++ clock /= m3; ++ } ++ ++ return (clock); ++ } ++} ++ ++uint32 ++BCMINITFN(si_clock)(si_t *sih) ++{ ++ if (sih->chippkg == BCM4709_PKG_ID) { ++ return NS_SI_CLOCK; ++ } ++ return NS_SLOW_SI_CLOCK; ++} ++ ++#if defined(BCMDBG) ++/* print interesting sbconfig registers */ ++void ++si_dumpregs(si_t *sih, struct bcmstrbuf *b) ++{ ++ si_info_t *sii; ++ uint origidx, intr_val = 0; ++ ++ sii = SI_INFO(sih); ++ origidx = sii->curidx; ++ ++ INTR_OFF(sii, intr_val); ++ if (CHIPTYPE(sih->socitype) == SOCI_SB) { ++ sb_dumpregs(sih, b); ++ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { ++ ai_dumpregs(sih, b); ++ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { ++ ub_dumpregs(sih, b); ++ } else { ++ ASSERT(0); ++ } ++ ++ si_setcoreidx(sih, origidx); ++ INTR_RESTORE(sii, intr_val); ++} ++#endif ++ ++#ifdef BCMDBG ++void ++si_view(si_t *sih, bool verbose) ++{ ++ if (CHIPTYPE(sih->socitype) == SOCI_SB) { ++ sb_view(sih, verbose); ++ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { ++ ai_view(sih, verbose); ++ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { ++ ub_view(sih, verbose); ++ } else { ++ ASSERT(0); ++ } ++} ++ ++void ++si_viewall(si_t *sih, bool verbose) ++{ ++ si_info_t *sii; ++ uint curidx, i; ++ uint intr_val = 0; ++ ++ sii = SI_INFO(sih); ++ curidx = sii->curidx; ++ ++ INTR_OFF(sii, intr_val); ++ if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { ++ ai_viewall(sih, verbose); ++ } else { ++ SI_ERROR(("si_viewall: num_cores %d\n", sii->numcores)); ++ for (i = 0; i < sii->numcores; i++) { ++ si_setcoreidx(sih, i); ++ si_view(sih, verbose); ++ } ++ } ++ si_setcoreidx(sih, curidx); ++ INTR_RESTORE(sii, intr_val); ++} ++#endif /* BCMDBG */ ++ ++/* return the slow clock source - LPO, XTAL, or PCI */ ++static uint ++si_slowclk_src(si_info_t *sii) ++{ ++ chipcregs_t *cc; ++ ++ ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID); ++ ++ if (sii->pub.ccrev < 6) { ++ return (SCC_SS_XTAL); ++ } else if (sii->pub.ccrev < 10) { ++ cc = (chipcregs_t *)si_setcoreidx(&sii->pub, sii->curidx); ++ return (R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_SS_MASK); ++ } else { /* Insta-clock */ ++ return (SCC_SS_XTAL); ++ } ++} ++ ++/* return the ILP (slowclock) min or max frequency */ ++static uint ++si_slowclk_freq(si_info_t *sii, bool max_freq, chipcregs_t *cc) ++{ ++ uint32 slowclk; ++ uint div; ++ ++ ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID); ++ ++ /* shouldn't be here unless we've established the chip has dynamic clk control */ ++ ASSERT(R_REG(sii->osh, &cc->capabilities) & CC_CAP_PWR_CTL); ++ ++ slowclk = si_slowclk_src(sii); ++ if (sii->pub.ccrev < 6) { ++ if (slowclk == SCC_SS_PCI) { ++ return (max_freq ? (PCIMAXFREQ / 64) : (PCIMINFREQ / 64)); ++ } else { ++ return (max_freq ? (XTALMAXFREQ / 32) : (XTALMINFREQ / 32)); ++ } ++ } else if (sii->pub.ccrev < 10) { ++ div = 4 * ++ (((R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1); ++ if (slowclk == SCC_SS_LPO) { ++ return (max_freq ? LPOMAXFREQ : LPOMINFREQ); ++ } else if (slowclk == SCC_SS_XTAL) { ++ return (max_freq ? (XTALMAXFREQ / div) : (XTALMINFREQ / div)); ++ } else if (slowclk == SCC_SS_PCI) { ++ return (max_freq ? (PCIMAXFREQ / div) : (PCIMINFREQ / div)); ++ } else { ++ ASSERT(0); ++ } ++ } else { ++ /* Chipc rev 10 is InstaClock */ ++ div = R_REG(sii->osh, &cc->system_clk_ctl) >> SYCC_CD_SHIFT; ++ div = 4 * (div + 1); ++ return (max_freq ? XTALMAXFREQ : (XTALMINFREQ / div)); ++ } ++ return (0); ++} ++ ++static void ++BCMINITFN(si_clkctl_setdelay)(si_info_t *sii, void *chipcregs) ++{ ++ chipcregs_t *cc = (chipcregs_t *)chipcregs; ++ uint slowmaxfreq, pll_delay, slowclk; ++ uint pll_on_delay, fref_sel_delay; ++ ++ pll_delay = PLL_DELAY; ++ ++ /* If the slow clock is not sourced by the xtal then add the xtal_on_delay ++ * since the xtal will also be powered down by dynamic clk control logic. ++ */ ++ ++ slowclk = si_slowclk_src(sii); ++ if (slowclk != SCC_SS_XTAL) { ++ pll_delay += XTAL_ON_DELAY; ++ } ++ ++ /* Starting with 4318 it is ILP that is used for the delays */ ++ slowmaxfreq = si_slowclk_freq(sii, (sii->pub.ccrev >= 10) ? FALSE : TRUE, cc); ++ ++ pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000; ++ fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000; ++ ++ W_REG(sii->osh, &cc->pll_on_delay, pll_on_delay); ++ W_REG(sii->osh, &cc->fref_sel_delay, fref_sel_delay); ++} ++ ++/* initialize power control delay registers */ ++void ++BCMINITFN(si_clkctl_init)(si_t *sih) ++{ ++ si_info_t *sii; ++ uint origidx = 0; ++ chipcregs_t *cc; ++ bool fast; ++ ++ if (!CCCTL_ENAB(sih)) { ++ return; ++ } ++ ++ sii = SI_INFO(sih); ++ fast = SI_FAST(sii); ++ if (!fast) { ++ origidx = sii->curidx; ++ if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) { ++ return; ++ } ++ } else if ((cc = (chipcregs_t *)CCREGS_FAST(sii)) == NULL) { ++ return; ++ } ++ ASSERT(cc != NULL); ++ ++ /* set all Instaclk chip ILP to 1 MHz */ ++ if (sih->ccrev >= 10) { ++ SET_REG(sii->osh, &cc->system_clk_ctl, SYCC_CD_MASK, ++ (ILP_DIV_1MHZ << SYCC_CD_SHIFT)); ++ } ++ ++ si_clkctl_setdelay(sii, (void *)(uintptr)cc); ++ ++ if (!fast) { ++ si_setcoreidx(sih, origidx); ++ } ++} ++ ++/* turn primary xtal and/or pll off/on */ ++int ++si_clkctl_xtal(si_t *sih, uint what, bool on) ++{ ++ switch (BUSTYPE(sih->bustype)) { ++ ++ default: ++ return (-1); ++ } ++ ++} ++ ++/* ++ * clock control policy function throught chipcommon ++ * ++ * set dynamic clk control mode (forceslow, forcefast, dynamic) ++ * returns true if we are forcing fast clock ++ * this is a wrapper over the next internal function ++ * to allow flexible policy settings for outside caller ++ */ ++bool ++si_clkctl_cc(si_t *sih, uint mode) ++{ ++ si_info_t *sii; ++ ++ sii = SI_INFO(sih); ++ ++ /* chipcommon cores prior to rev6 don't support dynamic clock control */ ++ if (sih->ccrev < 6) { ++ return FALSE; ++ } ++ ++ return _si_clkctl_cc(sii, mode); ++} ++ ++/* clk control mechanism through chipcommon, no policy checking */ ++static bool ++_si_clkctl_cc(si_info_t *sii, uint mode) ++{ ++ uint origidx = 0; ++ chipcregs_t *cc; ++ uint32 scc; ++ uint intr_val = 0; ++ bool fast = SI_FAST(sii); ++ ++ /* chipcommon cores prior to rev6 don't support dynamic clock control */ ++ if (sii->pub.ccrev < 6) { ++ return (FALSE); ++ } ++ ++ /* Chips with ccrev 10 are EOL and they don't have SYCC_HR which we use below */ ++ ASSERT(sii->pub.ccrev != 10); ++ ++ if (!fast) { ++ INTR_OFF(sii, intr_val); ++ origidx = sii->curidx; ++ ++ if ((BUSTYPE(sii->pub.bustype) == SI_BUS) && ++ si_setcore(&sii->pub, MIPS33_CORE_ID, 0) && ++ (si_corerev(&sii->pub) <= 7) && (sii->pub.ccrev >= 10)) { ++ goto done; ++ } ++ ++ cc = (chipcregs_t *) si_setcore(&sii->pub, CC_CORE_ID, 0); ++ } else if ((cc = (chipcregs_t *) CCREGS_FAST(sii)) == NULL) { ++ goto done; ++ } ++ ++ ASSERT(cc != NULL); ++ ++ if (!CCCTL_ENAB(&sii->pub) && (sii->pub.ccrev < 20)) { ++ goto done; ++ } ++ ++ switch (mode) { ++ case CLK_FAST: /* FORCEHT, fast (pll) clock */ ++ if (sii->pub.ccrev < 10) { ++ /* don't forget to force xtal back on before we clear SCC_DYN_XTAL.. */ ++ si_clkctl_xtal(&sii->pub, XTAL, ON); ++ SET_REG(sii->osh, &cc->slow_clk_ctl, (SCC_XC | SCC_FS | SCC_IP), SCC_IP); ++ } else if (sii->pub.ccrev < 20) { ++ OR_REG(sii->osh, &cc->system_clk_ctl, SYCC_HR); ++ } else { ++ OR_REG(sii->osh, &cc->clk_ctl_st, CCS_FORCEHT); ++ } ++ ++ /* wait for the PLL */ ++ if (PMUCTL_ENAB(&sii->pub)) { ++ uint32 htavail = CCS_HTAVAIL; ++ ++ SPINWAIT(((R_REG(sii->osh, &cc->clk_ctl_st) & htavail) == 0), ++ PMU_MAX_TRANSITION_DLY); ++ ASSERT(R_REG(sii->osh, &cc->clk_ctl_st) & htavail); ++ } else { ++ OSL_DELAY(PLL_DELAY); ++ } ++ break; ++ ++ case CLK_DYNAMIC: /* enable dynamic clock control */ ++ if (sii->pub.ccrev < 10) { ++ scc = R_REG(sii->osh, &cc->slow_clk_ctl); ++ scc &= ~(SCC_FS | SCC_IP | SCC_XC); ++ if ((scc & SCC_SS_MASK) != SCC_SS_XTAL) { ++ scc |= SCC_XC; ++ } ++ W_REG(sii->osh, &cc->slow_clk_ctl, scc); ++ ++ /* for dynamic control, we have to release our xtal_pu "force on" */ ++ if (scc & SCC_XC) { ++ si_clkctl_xtal(&sii->pub, XTAL, OFF); ++ } ++ } else if (sii->pub.ccrev < 20) { ++ /* Instaclock */ ++ AND_REG(sii->osh, &cc->system_clk_ctl, ~SYCC_HR); ++ } else { ++ AND_REG(sii->osh, &cc->clk_ctl_st, ~CCS_FORCEHT); ++ } ++ break; ++ ++ default: ++ ASSERT(0); ++ } ++ ++done: ++ if (!fast) { ++ si_setcoreidx(&sii->pub, origidx); ++ INTR_RESTORE(sii, intr_val); ++ } ++ return (mode == CLK_FAST); ++} ++ ++/* Build device path. Support SI, PCI, and JTAG for now. */ ++int ++BCMNMIATTACHFN(si_devpath)(si_t *sih, char *path, int size) ++{ ++ int slen; ++ ++ ASSERT(path != NULL); ++ ASSERT(size >= SI_DEVPATH_BUFSZ); ++ ++ if (!path || size <= 0) ++ return -1; ++ ++ switch (BUSTYPE(sih->bustype)) { ++ case SI_BUS: ++ slen = snprintf(path, (size_t)size, "sb/%u/", si_coreidx(sih)); ++ break; ++ default: ++ slen = -1; ++ ASSERT(0); ++ break; ++ } ++ ++ if (slen < 0 || slen >= size) { ++ path[0] = '\0'; ++ return -1; ++ } ++ ++ return 0; ++} ++ ++char * ++BCMATTACHFN(si_coded_devpathvar)(si_t *sih, char *varname, int var_len, const char *name) ++{ ++ char pathname[SI_DEVPATH_BUFSZ + 32]; ++ char devpath[SI_DEVPATH_BUFSZ + 32]; ++ char *p; ++ int idx; ++ int len; ++ ++ /* try to get compact devpath if it exist */ ++ if (si_devpath(sih, devpath, SI_DEVPATH_BUFSZ) == 0) { ++ len = strlen(devpath); ++ devpath[len - 1] = '\0'; ++ for (idx = 0; idx < SI_MAXCORES; idx++) { ++ snprintf(pathname, SI_DEVPATH_BUFSZ, "devpath%d", idx); ++ if ((p = getvar(NULL, pathname)) == NULL) { ++ continue; ++ } ++ ++ if (strncmp(p, devpath, len) == 0) { ++ snprintf(varname, var_len, "%d:%s", idx, name); ++ return varname; ++ } ++ } ++ } ++ ++ return NULL; ++} ++ ++/* Get a variable, but only if it has a devpath prefix */ ++int ++BCMATTACHFN(si_getdevpathintvar)(si_t *sih, const char *name) ++{ ++#if defined(BCMBUSTYPE) && (BCMBUSTYPE == SI_BUS) ++ return (getintvar(NULL, name)); ++#else ++ char varname[SI_DEVPATH_BUFSZ + 32]; ++ int val; ++ ++ si_devpathvar(sih, varname, sizeof(varname), name); ++ ++ if ((val = getintvar(NULL, varname)) != 0) { ++ return val; ++ } ++ ++ /* try to get compact devpath if it exist */ ++ if (si_coded_devpathvar(sih, varname, sizeof(varname), name) == NULL) { ++ return 0; ++ } ++ ++ return (getintvar(NULL, varname)); ++#endif /* BCMBUSTYPE && BCMBUSTYPE == SI_BUS */ ++} ++ ++/* Concatenate the dev path with a varname into the given 'var' buffer ++ * and return the 'var' pointer. ++ * Nothing is done to the arguments if len == 0 or var is NULL, var is still returned. ++ * On overflow, the first char will be set to '\0'. ++ */ ++static char * ++BCMATTACHFN(si_devpathvar)(si_t *sih, char *var, int len, const char *name) ++{ ++ uint path_len; ++ ++ if (!var || len <= 0) { ++ return var; ++ } ++ ++ if (si_devpath(sih, var, len) == 0) { ++ path_len = strlen(var); ++ ++ if (strlen(name) + 1 > (uint)(len - path_len)) { ++ var[0] = '\0'; ++ } else { ++ strncpy(var + path_len, name, len - path_len - 1); ++ } ++ } ++ ++ return var; ++} ++ ++ ++#if defined(BCMDBG) ++#endif ++ ++/* mask&set gpio output enable bits */ ++uint32 ++si_gpioouten(si_t *sih, uint32 mask, uint32 val, uint8 priority) ++{ ++ uint regoff; ++ ++ regoff = 0; ++ ++ /* gpios could be shared on router platforms ++ * ignore reservation if it's high priority (e.g., test apps) ++ */ ++ if ((priority != GPIO_HI_PRIORITY) && ++ (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) { ++ mask = priority ? (si_gpioreservation & mask) : ++ ((si_gpioreservation | mask) & ~(si_gpioreservation)); ++ val &= mask; ++ } ++ ++ regoff = OFFSETOF(chipcregs_t, gpioouten); ++ return (si_corereg(sih, SI_CC_IDX, regoff, mask, val)); ++} ++ ++/* mask&set gpio output bits */ ++uint32 ++si_gpioout(si_t *sih, uint32 mask, uint32 val, uint8 priority) ++{ ++ uint regoff; ++ ++ regoff = 0; ++ ++ /* gpios could be shared on router platforms ++ * ignore reservation if it's high priority (e.g., test apps) ++ */ ++ if ((priority != GPIO_HI_PRIORITY) && ++ (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) { ++ mask = priority ? (si_gpioreservation & mask) : ++ ((si_gpioreservation | mask) & ~(si_gpioreservation)); ++ val &= mask; ++ } ++ ++ regoff = OFFSETOF(chipcregs_t, gpioout); ++ return (si_corereg(sih, SI_CC_IDX, regoff, mask, val)); ++} +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/siutils_priv.h b/drivers/net/ethernet/broadcom/gmac/src/shared/siutils_priv.h +--- a/drivers/net/ethernet/broadcom/gmac/src/shared/siutils_priv.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/gmac/src/shared/siutils_priv.h 2017-11-09 17:53:44.066299000 +0800 +@@ -0,0 +1,236 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Include file private to the SOC Interconnect support files. ++ * ++ * $Id: siutils_priv.h 302333 2011-12-11 01:47:49Z $ ++ */ ++ ++#ifndef _siutils_priv_h_ ++#define _siutils_priv_h_ ++ ++#ifdef BCMDBG_ERR ++#define SI_ERROR(args) printf args ++#else ++#define SI_ERROR(args) ++#endif /* BCMDBG_ERR */ ++ ++#ifdef BCMDBG ++#define SI_MSG(args) printf args ++#else ++#define SI_MSG(args) ++#endif /* BCMDBG */ ++ ++#ifdef BCMDBG_SI ++#define SI_VMSG(args) printf args ++#else ++#define SI_VMSG(args) ++#endif ++ ++#define IS_SIM(chippkg) ((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID)) ++ ++typedef uint32 (*si_intrsoff_t)(void *intr_arg); ++typedef void (*si_intrsrestore_t)(void *intr_arg, uint32 arg); ++typedef bool (*si_intrsenabled_t)(void *intr_arg); ++ ++typedef struct gpioh_item { ++ void *arg; ++ bool level; ++ gpio_handler_t handler; ++ uint32 event; ++ struct gpioh_item *next; ++} gpioh_item_t; ++ ++/* misc si info needed by some of the routines */ ++typedef struct si_info { ++ struct si_pub pub; /* back plane public state (must be first field) */ ++ ++ void *osh; /* osl os handle */ ++ void *sdh; /* bcmsdh handle */ ++ ++ uint dev_coreid; /* the core provides driver functions */ ++ void *intr_arg; /* interrupt callback function arg */ ++ si_intrsoff_t intrsoff_fn; /* turns chip interrupts off */ ++ si_intrsrestore_t intrsrestore_fn; /* restore chip interrupts */ ++ si_intrsenabled_t intrsenabled_fn; /* check if interrupts are enabled */ ++ ++ void *pch; /* PCI/E core handle */ ++ gpioh_item_t *gpioh_head; /* GPIO event handlers list */ ++ bool memseg; /* flag to toggle MEM_SEG register */ ++ char *vars; ++ uint varsz; ++ ++ void *curmap; /* current regs va */ ++ void *regs[SI_MAXCORES]; /* other regs va */ ++ ++ uint curidx; /* current core index */ ++ uint numcores; /* # discovered cores */ ++ uint coreid[SI_MAXCORES]; /* id of each core */ ++ uint32 coresba[SI_MAXCORES]; /* backplane address of each core */ ++ void *regs2[SI_MAXCORES]; /* va of each core second register set (usbh20) */ ++ uint32 coresba2[SI_MAXCORES]; /* address of each core second register set (usbh20) */ ++ uint32 coresba_size[SI_MAXCORES]; /* backplane address space size */ ++ uint32 coresba2_size[SI_MAXCORES]; /* second address space size */ ++ ++ void *curwrap; /* current wrapper va */ ++ void *wrappers[SI_MAXCORES]; /* other cores wrapper va */ ++ uint32 wrapba[SI_MAXCORES]; /* address of controlling wrapper */ ++ ++ uint32 cia[SI_MAXCORES]; /* erom cia entry for each core */ ++ uint32 cib[SI_MAXCORES]; /* erom cia entry for each core */ ++ uint32 oob_router; /* oob router registers for axi */ ++} si_info_t; ++ ++#define SI_INFO(sih) (si_info_t *)(uintptr)sih ++ ++#define GOODCOREADDR(x, b) (((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \ ++ ISALIGNED((x), SI_CORE_SIZE)) ++#define GOODREGS(regs) ((regs) != NULL && ISALIGNED((uintptr)(regs), SI_CORE_SIZE)) ++#define BADCOREADDR 0 ++#define GOODIDX(idx) (((uint)idx) < SI_MAXCORES) ++#define NOREV -1 /* Invalid rev */ ++ ++#define PCI(si) ((BUSTYPE((si)->pub.bustype) == PCI_BUS) && \ ++ ((si)->pub.buscoretype == PCI_CORE_ID)) ++ ++#define PCIE_GEN1(si) ((BUSTYPE((si)->pub.bustype) == PCI_BUS) && \ ++ ((si)->pub.buscoretype == PCIE_CORE_ID)) ++ ++#define PCIE_GEN2(si) ((BUSTYPE((si)->pub.bustype) == PCI_BUS) && \ ++ ((si)->pub.buscoretype == PCIE2_CORE_ID)) ++ ++#define PCIE(si) (PCIE_GEN1(si) || PCIE_GEN2(si)) ++ ++#define PCMCIA(si) ((BUSTYPE((si)->pub.bustype) == PCMCIA_BUS) && ((si)->memseg == TRUE)) ++ ++/* Newer chips can access PCI/PCIE and CC core without requiring to change ++ * PCI BAR0 WIN ++ */ ++#define SI_FAST(si) (PCIE(si) || (PCI(si) && ((si)->pub.buscorerev >= 13))) ++ ++#define PCIEREGS(si) (((char *)((si)->curmap) + PCI_16KB0_PCIREGS_OFFSET)) ++#define CCREGS_FAST(si) (((char *)((si)->curmap) + PCI_16KB0_CCREGS_OFFSET)) ++ ++/* ++ * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts before/ ++ * after core switching to avoid invalid register accesss inside ISR. ++ */ ++#define INTR_OFF(si, intr_val) \ ++ if ((si)->intrsoff_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ ++ intr_val = (*(si)->intrsoff_fn)((si)->intr_arg); } ++#define INTR_RESTORE(si, intr_val) \ ++ if ((si)->intrsrestore_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ ++ (*(si)->intrsrestore_fn)((si)->intr_arg, intr_val); } ++ ++/* dynamic clock control defines */ ++#define LPOMINFREQ 25000 /* low power oscillator min */ ++#define LPOMAXFREQ 43000 /* low power oscillator max */ ++#define XTALMINFREQ 19800000 /* 20 MHz - 1% */ ++#define XTALMAXFREQ 20200000 /* 20 MHz + 1% */ ++#define PCIMINFREQ 25000000 /* 25 MHz */ ++#define PCIMAXFREQ 34000000 /* 33 MHz + fudge */ ++ ++#define ILP_DIV_5MHZ 0 /* ILP = 5 MHz */ ++#define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */ ++ ++/* GPIO Based LED powersave defines */ ++#define DEFAULT_GPIO_ONTIME 10 /* Default: 10% on */ ++#define DEFAULT_GPIO_OFFTIME 90 /* Default: 10% on */ ++#ifndef DEFAULT_GPIOTIMERVAL ++#define DEFAULT_GPIOTIMERVAL ((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME) ++#endif ++ ++#define sb_scan(a, b, c) do {} while (0) ++#define sb_coreid(a) (0) ++#define sb_intflag(a) (0) ++#define sb_flag(a) (0) ++#define sb_setint(a, b) do {} while (0) ++#define sb_corevendor(a) (0) ++#define sb_corerev(a) (0) ++#define sb_corereg(a, b, c, d, e) (0) ++#define sb_iscoreup(a) (false) ++#define sb_setcoreidx(a, b) (0) ++#define sb_core_cflags(a, b, c) (0) ++#define sb_core_cflags_wo(a, b, c) do {} while (0) ++#define sb_core_sflags(a, b, c) (0) ++#define sb_commit(a) do {} while (0) ++#define sb_base(a) (0) ++#define sb_size(a) (0) ++#define sb_core_reset(a, b, c) do {} while (0) ++#define sb_core_disable(a, b) do {} while (0) ++#define sb_addrspace(a, b) (0) ++#define sb_addrspacesize(a, b) (0) ++#define sb_numaddrspaces(a) (0) ++#define sb_set_initiator_to(a, b, c) (0) ++#define sb_taclear(a, b) (false) ++#define sb_view(a, b) do {} while (0) ++#define sb_viewall(a, b) do {} while (0) ++#define sb_dump(a, b) do {} while (0) ++#define sb_dumpregs(a, b) do {} while (0) ++ ++ ++/* AMBA Interconnect exported externs */ ++extern si_t *ai_attach(uint pcidev, osl_t *osh, void *regs, uint bustype, ++ void *sdh, char **vars, uint *varsz); ++extern si_t *ai_kattach(osl_t *osh); ++extern void ai_scan(si_t *sih, void *regs, uint devid); ++extern uint ai_flag(si_t *sih); ++extern void ai_setint(si_t *sih, int siflag); ++extern uint ai_coreidx(si_t *sih); ++extern uint ai_corevendor(si_t *sih); ++extern uint ai_corerev(si_t *sih); ++extern bool ai_iscoreup(si_t *sih); ++extern void *ai_setcoreidx(si_t *sih, uint coreidx); ++extern uint32 ai_core_cflags(si_t *sih, uint32 mask, uint32 val); ++extern void ai_core_cflags_wo(si_t *sih, uint32 mask, uint32 val); ++extern uint32 ai_core_sflags(si_t *sih, uint32 mask, uint32 val); ++extern uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val); ++extern void ai_core_reset(si_t *sih, uint32 bits, uint32 resetbits); ++extern void ai_core_disable(si_t *sih, uint32 bits); ++extern int ai_numaddrspaces(si_t *sih); ++extern uint32 ai_addrspace(si_t *sih, uint asidx); ++extern uint32 ai_addrspacesize(si_t *sih, uint asidx); ++extern void ai_coreaddrspaceX(si_t *sih, uint asidx, uint32 *addr, uint32 *size); ++extern uint ai_wrap_reg(si_t *sih, uint32 offset, uint32 mask, uint32 val); ++#ifdef BCMDBG ++extern void ai_view(si_t *sih, bool verbose); ++extern void ai_viewall(si_t *sih, bool verbose); ++#endif /* BCMDBG */ ++#if defined(BCMDBG) ++extern void ai_dumpregs(si_t *sih, struct bcmstrbuf *b); ++#endif ++ ++ ++#define ub_scan(a, b, c) do {} while (0) ++#define ub_flag(a) (0) ++#define ub_setint(a, b) do {} while (0) ++#define ub_coreidx(a) (0) ++#define ub_corevendor(a) (0) ++#define ub_corerev(a) (0) ++#define ub_iscoreup(a) (0) ++#define ub_setcoreidx(a, b) (0) ++#define ub_core_cflags(a, b, c) (0) ++#define ub_core_cflags_wo(a, b, c) do {} while (0) ++#define ub_core_sflags(a, b, c) (0) ++#define ub_corereg(a, b, c, d, e) (0) ++#define ub_core_reset(a, b, c) do {} while (0) ++#define ub_core_disable(a, b) do {} while (0) ++#define ub_numaddrspaces(a) (0) ++#define ub_addrspace(a, b) (0) ++#define ub_addrspacesize(a, b) (0) ++#define ub_view(a, b) do {} while (0) ++#define ub_dumpregs(a, b) do {} while (0) ++ ++#endif /* _siutils_priv_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/mdio/Kconfig b/drivers/net/ethernet/broadcom/mdio/Kconfig +--- a/drivers/net/ethernet/broadcom/mdio/Kconfig 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/mdio/Kconfig 2017-11-09 17:53:44.076300000 +0800 +@@ -0,0 +1,23 @@ ++# ++# Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++# ++# Permission to use, copy, modify, and/or distribute this software for any ++# purpose with or without fee is hereby granted, provided that the above ++# copyright notice and this permission notice appear in all copies. ++# ++# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++# ++config MDIO_XGS_IPROC ++ tristate "BRCM XGS iProc MDIO support" ++ depends on ARCH_XGS_IPROC ++ default n ++ help ++ MDIO support ++ ++ If unsure, say N. +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/mdio/Makefile b/drivers/net/ethernet/broadcom/mdio/Makefile +--- a/drivers/net/ethernet/broadcom/mdio/Makefile 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/mdio/Makefile 2017-11-09 17:53:44.077310000 +0800 +@@ -0,0 +1,17 @@ ++# ++# Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++# ++# Permission to use, copy, modify, and/or distribute this software for any ++# purpose with or without fee is hereby granted, provided that the above ++# copyright notice and this permission notice appear in all copies. ++# ++# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++# ++obj-$(CONFIG_MDIO_XGS_IPROC) := iproc_mii.o ++iproc_mii-objs := ccb_mdio.o cmicd_mdio.o ccg_mdio.o iproc_mdio.o +\ No newline at end of file +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/mdio/ccb_mdio.c b/drivers/net/ethernet/broadcom/mdio/ccb_mdio.c +--- a/drivers/net/ethernet/broadcom/mdio/ccb_mdio.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/mdio/ccb_mdio.c 2017-11-09 17:53:44.079291000 +0800 +@@ -0,0 +1,873 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ */ ++ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include ++#include ++ ++#include "iproc_mdio.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "iproc_mdio_dev.h" ++ ++#ifdef CONFIG_OF_MDIO ++#include ++#include ++#include ++static struct iproc_mdiobus_data iproc_mdiobus_data; ++#define __devinit /* */ ++#define __devexit /* */ ++#endif /* CONFIG_OF_MDIO */ ++ ++#ifndef CONFIG_OF_MDIO ++#define CCB_MDIO_BASE_ADDRESS IPROC_MII_MGMT_CTL ++#endif ++ ++#define R_REG(reg) ioread32(ccb_mdio->base + (reg&0x0fff)) ++#define W_REG(reg, val) iowrite32(val, ccb_mdio->base + (reg&0x0fff)) ++ ++#define MII_ERR_VAL 0x0001 ++#define MII_MSG_VAL 0x0002 ++#define MII_DBG_VAL 0x0004 ++//static u32 mii_msg_level = MII_ERR_VAL; ++ ++#if defined(BCMDBG) || defined(BCMDBG_ERR) ++#define MII_ERR(args) do {if (mii_msg_level & MII_ERR_VAL) printk args;} while (0) ++#else ++#define MII_ERR(args) ++#endif ++ ++#ifdef BCMDBG ++#define MII_MSG(args) do {if (mii_msg_level & MII_MSG_VAL) printk args;} while (0) ++#define MII_DBG(args) do {if (mii_msg_level & MII_DBG_VAL) printk args;} while (0) ++#else ++#define MII_MSG(args) ++#define MII_DBG(args) ++#endif ++ ++#define MII_EN_CHK \ ++ {\ ++ if (!ccb_mdio->base) { \ ++ return MII_ERR_INIT; \ ++ } \ ++ if (!(R_REG(MII_MGMT) & 0x7f)) { \ ++ return MII_ERR_INTERNAL; \ ++ } \ ++ } ++ ++#define MII_TRIES 100000 ++#define MII_POLL_USEC 20 ++ ++struct mdio_device_data { ++ mdio_info_t *mdio; ++ int init; ++}; ++ ++static struct mdio_device_data mdio_devices={0}; ++static uint32_t ccb_mdio_clk_rate; ++ ++#define DRIVER_VERSION "0.01" ++#define DRIVER_NAME "iproc mdio" ++ ++static int mdio_major; ++static struct cdev mdio_cdev; ++ ++#define MDIO_IOC_OP_EXTERNAL_READ 0 ++#define MDIO_IOC_OP_EXTERNAL_WRITE 1 ++#define MDIO_IOC_OP_LOCAL_READ 2 ++#define MDIO_IOC_OP_LOCAL_WRITE 3 ++ ++ ++struct ccb_mdio_ctrl { ++ void __iomem *base; ++ int ref_cnt; ++}; ++ ++struct ccb_mdiobus_private { ++ /* iproc_mdiobus_data field have to be placed at the beginning of ++ * mdiobus private data */ ++ struct iproc_mdiobus_data bus_data; ++ struct ccb_mdio_ctrl *hw_ctrl; ++}; ++ ++static struct ccb_mdio_ctrl *ccb_mdio = NULL; ++ ++#ifndef CONFIG_OF_MDIO ++static struct resource ccb_mdio_mem = { ++ .name = "ccb_mdio", ++ .start = CCB_MDIO_BASE_ADDRESS, ++ .end = CCB_MDIO_BASE_ADDRESS + 0x1000 - 1, ++ .flags = IORESOURCE_MEM, ++}; ++#endif ++ ++/* Function : ccb_mii_read ++ * - Read operation. ++ * Return : ++ * Note : ++ */ ++int ++ccb_mii_read(int dev_type, int phy_addr, int reg_off, uint16_t *data) ++{ ++ int i; ++ uint32_t ctrl = 0; ++ unsigned long flags; ++ mdio_info_t *mdio = NULL; ++ ++ MII_EN_CHK; ++ ++ mdio = mdio_devices.mdio; ++ ++ spin_lock_irqsave(&mdio->lock, flags); ++ ++ ctrl = R_REG(MII_MGMT); ++ if (dev_type == MII_DEV_LOCAL) { ++ ctrl &= ~MII_MGMT_EXP_MASK; ++ } else { ++ ctrl |= MII_MGMT_EXP_MASK; ++ } ++ W_REG(MII_MGMT, ctrl); ++ MII_DBG(("MII READ: write(0x%x)=0x%x\n",MII_MGMT, ctrl)); ++ ++ for (i = 0; i < MII_TRIES; i++) { ++ ctrl = R_REG(MII_MGMT); ++ if (!(ctrl & MII_MGMT_BSY_MASK)) { ++ break; ++ } ++ udelay(MII_POLL_USEC); ++ } ++ if (i >= MII_TRIES) { ++ MII_ERR(("\n%s: BUSY stuck: ctrl=0x%x, count=%d\n", __FUNCTION__, ctrl, i)); ++ spin_unlock_irqrestore(&mdio->lock, flags); ++ return -1; ++ } ++ ++ ctrl = (((1 << MII_CMD_DATA_SB_SHIFT) & MII_CMD_DATA_SB_MASK) | ++ ((2 << MII_CMD_DATA_OP_SHIFT) & MII_CMD_DATA_OP_MASK) | ++ ((phy_addr << MII_CMD_DATA_PA_SHIFT) & MII_CMD_DATA_PA_MASK) | ++ ((reg_off << MII_CMD_DATA_RA_SHIFT) & MII_CMD_DATA_RA_MASK) | ++ ((2 << MII_CMD_DATA_TA_SHIFT) & MII_CMD_DATA_TA_MASK)); ++ W_REG(MII_CMD_DATA, ctrl); ++ MII_DBG(("MII READ: write(0x%x)=0x%x\n",MII_CMD_DATA, ctrl)); ++ ++ for (i = 0; i < MII_TRIES; i++) { ++ ctrl = R_REG(MII_MGMT); ++ if (!(ctrl & MII_MGMT_BSY_MASK)) { ++ break; ++ } ++ udelay(MII_POLL_USEC); ++ } ++ if (i >= MII_TRIES) { ++ MII_ERR(("\n%s: BUSY stuck: ctrl=0x%x, count=%d\n", __FUNCTION__, ctrl, i)); ++ spin_unlock_irqrestore(&mdio->lock, flags); ++ return -1; ++ } ++ ++ ctrl = R_REG(MII_CMD_DATA); ++ ++ MII_DBG(("MDIO READ: addr=%x off=%x value=%x\n", phy_addr, reg_off, ctrl)); ++ ++ spin_unlock_irqrestore(&mdio->lock, flags); ++ ++ *data = (ctrl & 0xffff); ++ return 0; ++} ++ ++/* Function : ccb_mii_write ++ * - Write operation. ++ * Return : ++ * Note : ++ */ ++int ++ccb_mii_write(int dev_type, int phy_addr, int reg_off, uint16_t data) ++{ ++ int i; ++ uint32_t ctrl = 0; ++ unsigned long flags; ++ mdio_info_t *mdio = NULL; ++ ++ MII_DBG(("MDIO WRITE: addr=%x off=%x\n", phy_addr, reg_off)); ++ ++ MII_EN_CHK; ++ ++ mdio = mdio_devices.mdio; ++ ++ spin_lock_irqsave(&mdio->lock, flags); ++ ++ ctrl = R_REG(MII_MGMT); ++ if (dev_type == MII_DEV_LOCAL) { ++ ctrl &= ~MII_MGMT_EXP_MASK; ++ } else { ++ ctrl |= MII_MGMT_EXP_MASK; ++ } ++ W_REG(MII_MGMT, ctrl); ++ MII_DBG(("MII WRITE: write(0x%x)=0x%x\n",MII_MGMT, ctrl)); ++ ++ for (i = 0; i < MII_TRIES; i++) { ++ ctrl = R_REG(MII_MGMT); ++ if (!(ctrl & MII_MGMT_BSY_MASK)) { ++ break; ++ } ++ udelay(MII_POLL_USEC); ++ } ++ if (i >= MII_TRIES) { ++ MII_ERR(("\n%s: BUSY stuck: ctrl=0x%x, count=%d\n", __FUNCTION__, ctrl, i)); ++ spin_unlock_irqrestore(&mdio->lock, flags); ++ return -1; ++ } ++ ++ ctrl = (((1 << MII_CMD_DATA_SB_SHIFT) & MII_CMD_DATA_SB_MASK) | ++ ((1 << MII_CMD_DATA_OP_SHIFT) & MII_CMD_DATA_OP_MASK) | ++ ((phy_addr << MII_CMD_DATA_PA_SHIFT) & MII_CMD_DATA_PA_MASK) | ++ ((reg_off << MII_CMD_DATA_RA_SHIFT) & MII_CMD_DATA_RA_MASK) | ++ ((2 << MII_CMD_DATA_TA_SHIFT) & MII_CMD_DATA_TA_MASK) | ++ ((data << MII_CMD_DATA_DATA_SHIFT) & MII_CMD_DATA_DATA_MASK)); ++ W_REG(MII_CMD_DATA, ctrl); ++ MII_DBG(("MII WRITE: write(0x%x)=0x%x\n",MII_CMD_DATA, ctrl)); ++ ++ ++ for (i = 0; i < MII_TRIES; i++) { ++ ctrl = R_REG(MII_MGMT); ++ if (!(ctrl & MII_MGMT_BSY_MASK)) { ++ break; ++ } ++ udelay(MII_POLL_USEC); ++ } ++ if (i >= MII_TRIES) { ++ MII_ERR(("\n%s: BUSY stuck: ctrl=0x%x, count=%d\n", __FUNCTION__, ctrl, i)); ++ spin_unlock_irqrestore(&mdio->lock, flags); ++ return -1; ++ } ++ ++ spin_unlock_irqrestore(&mdio->lock, flags); ++ ++ return MII_ERR_NONE; ++} ++ ++/* Function : ccb_mii_freq_set ++ * - Set MII management interface frequency. ++ * Return : ++ * Note : ++ * ++ */ ++int ++ccb_mii_freq_set(int speed_khz) ++{ ++ int rv = MII_ERR_NONE; ++ uint32_t divider = 0; ++ uint32_t mgmt = 0; ++ ++ MII_DBG(("MDIO FREQ SET: %d KHz\n", speed_khz)); ++ ++ /* host clock 66MHz device value the MDCDIV field */ ++ /* resultant MDIO clock should not exceed 2.5MHz */ ++ ++ if (speed_khz > 2500) { ++ MII_ERR(("\n%s: Maximum MDIO frequency is 2.5MHz\n", __FUNCTION__)); ++ return MII_ERR_PARAM; ++ } ++ ++ divider = ccb_mdio_clk_rate / (1000*speed_khz); ++ divider = (divider & MII_MGMT_MDCDIV_MASK); ++ if (divider > 0x7f) { ++ /* make sure the minimum configurable frequency */ ++ divider = 0x7f; ++ } ++ mgmt = R_REG(MII_MGMT); ++ mgmt &= ~MII_MGMT_MDCDIV_MASK; ++ mgmt |= divider; ++ ++ W_REG(MII_MGMT, mgmt); ++ MII_DBG(("MII FREQ(%d KHz): write(0x%x)=0x%x\n",speed_khz, MII_MGMT, mgmt)); ++ ++ return rv; ++} ++ ++static int ++mdio_open(struct inode *inode, struct file *filp) ++{ ++ filp->private_data = mdio_devices.mdio; ++ return 0; ++} ++ ++static int ++mdio_release(struct inode *inode, struct file *filp) ++{ ++ return 0; ++} ++ ++static int mdio_message(mdio_info_t *mdio, ++ struct mdio_ioc_transfer *u_xfers, unsigned n_xfers, int op) ++{ ++ ++ uint8_t pa, ra; ++ uint16_t regval; ++ ++ pa = u_xfers->pa; ++ ra = u_xfers->ra; ++ ++ MII_DBG(("mdio_message: op = %d\n", op)); ++ ++ if (op == MDIO_IOC_OP_LOCAL_READ) { ++ iproc_mii_read(MII_DEV_LOCAL, pa, ra, ®val); ++ u_xfers->rx_buf = regval; ++ } ++ ++ if (op == MDIO_IOC_OP_LOCAL_WRITE) { ++ iproc_mii_write(MII_DEV_LOCAL, pa, ra, u_xfers->tx_buf); ++ } ++ ++ if (op == MDIO_IOC_OP_EXTERNAL_READ) { ++ iproc_mii_read(MII_DEV_EXT, pa, ra, ®val); ++ u_xfers->rx_buf = regval; ++ } ++ ++ if (op == MDIO_IOC_OP_EXTERNAL_WRITE) { ++ iproc_mii_write(MII_DEV_EXT, pa, ra, u_xfers->tx_buf); ++ } ++ return 0; ++} ++ ++static long ++mdio_ioctl(struct file *filp, ++ unsigned int cmd, unsigned long arg) ++{ ++ int err = 0; ++ int retval = 0; ++ int ioc_op = 0; ++ uint32_t tmp; ++ unsigned n_ioc; ++ struct mdio_ioc_transfer *ioc, *uf; ++ mdio_info_t *mdio; ++ ++ MII_DBG(("mdio_ioctl: cmd = %d\n", cmd)); ++ ++ /* Check type and command number */ ++ if (_IOC_TYPE(cmd) != MDIO_IOC_MAGIC){ ++ return -ENOTTY; ++ } ++ ++ /* Check access direction once here; don't repeat below. ++ * IOC_DIR is from the user perspective, while access_ok is ++ * from the kernel perspective; so they look reversed. ++ */ ++ if (_IOC_DIR(cmd) & _IOC_READ) { ++ err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd)); ++ } ++ if (err == 0 && _IOC_DIR(cmd) & _IOC_WRITE) { ++ err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)); ++ } ++ if (err) { ++ return -EFAULT; ++ } ++ ++ mdio = (mdio_info_t *)filp->private_data; ++ ++ switch (cmd) { ++ case MDIO_IOC_EXTERNAL_R_REG: ++ ioc_op = MDIO_IOC_OP_EXTERNAL_READ; ++ break; ++ case MDIO_IOC_EXTERNAL_W_REG: ++ ioc_op = MDIO_IOC_OP_EXTERNAL_WRITE; ++ break; ++ case MDIO_IOC_LOCAL_R_REG: ++ ioc_op = MDIO_IOC_OP_LOCAL_READ; ++ break; ++ case MDIO_IOC_LOCAL_W_REG: ++ ioc_op = MDIO_IOC_OP_LOCAL_WRITE; ++ break; ++ } ++ ++ tmp = _IOC_SIZE(cmd); ++ if ((tmp % sizeof(struct mdio_ioc_transfer)) != 0) { ++ retval = -EINVAL; ++ return retval; ++ } ++ n_ioc = tmp / sizeof(struct mdio_ioc_transfer); ++ if (n_ioc == 0) { ++ return 0; ++ } ++ ++ /* copy into scratch area */ ++ ioc = kmalloc(tmp, GFP_KERNEL); ++ if (!ioc) { ++ retval = -ENOMEM; ++ return retval; ++ } ++ if (__copy_from_user(ioc, (void __user *)arg, tmp)) { ++ kfree(ioc); ++ retval = -EFAULT; ++ return retval; ++ } ++ /* translate to mdio_message, execute */ ++ retval = mdio_message(mdio, ioc, n_ioc, ioc_op); ++ ++ if ((ioc_op == MDIO_IOC_OP_EXTERNAL_READ) || (ioc_op == MDIO_IOC_OP_LOCAL_READ)) { ++ uf = (struct mdio_ioc_transfer *)arg; ++ if (__copy_to_user((u8 __user *)&uf->rx_buf, (uint8_t *)&ioc->rx_buf, 2)) { ++ kfree(ioc); ++ retval = -EFAULT; ++ return retval; ++ } ++ } ++ kfree(ioc); ++ ++ return 0; ++} ++ ++static const struct file_operations mdio_fops = { ++ .open = mdio_open, ++ .release = mdio_release, ++ .unlocked_ioctl = mdio_ioctl, ++ .owner = THIS_MODULE, ++}; ++ ++static int _mdio_handler_init(void) ++{ ++ mdio_info_t *mdio = NULL; ++ ++ mdio = kmalloc(sizeof(mdio_info_t), GFP_KERNEL); ++ if (mdio == NULL) { ++ MII_ERR(("mdio_init: out of memory\n")); ++ return -ENOMEM; ++ } ++ memset(mdio, 0, sizeof(mdio_info_t)); ++ ++ /* Initialize lock */ ++ spin_lock_init(&mdio->lock); ++ ++ mdio_devices.mdio = mdio; ++ mdio_devices.init = 1; ++ ++ return 0; ++} ++ ++ ++static int ccb_mdiobus_read(struct mii_bus *bus, int phy_id, int regnum) ++{ ++ struct ccb_mdiobus_private *bus_priv = bus->priv; ++ struct iproc_mdiobus_data *bus_data = &bus_priv->bus_data; ++ uint16_t data; ++ int dev_type = 0; ++ int err; ++ ++ if (IPROC_MDIOBUS_TYPE_INTERNAL == bus_data->phybus_type) { ++ dev_type = MII_DEV_LOCAL; ++ } else if (IPROC_MDIOBUS_TYPE_EXTERNAL == bus_data->phybus_type) { ++ dev_type = MII_DEV_EXT; ++ } else { ++ return -EINVAL; ++ } ++ err = ccb_mii_read(dev_type, phy_id, regnum, &data); ++ if (err < 0) { ++ return err; ++ } else { ++ return data; ++ } ++} ++ ++static int ccb_mdiobus_write(struct mii_bus *bus, int phy_id, ++ int regnum, u16 val) ++{ ++ struct ccb_mdiobus_private *bus_priv = bus->priv; ++ struct iproc_mdiobus_data *bus_data = &bus_priv->bus_data; ++ int dev_type = 0; ++ ++ if (IPROC_MDIOBUS_TYPE_INTERNAL == bus_data->phybus_type) { ++ dev_type = MII_DEV_LOCAL; ++ } else if (IPROC_MDIOBUS_TYPE_EXTERNAL == bus_data->phybus_type) { ++ dev_type = MII_DEV_EXT; ++ } else { ++ return -EINVAL; ++ } ++ ++ return ccb_mii_write(dev_type, phy_id, regnum, val); ++} ++ ++static void __maybe_unused ccb_mdiobus_test(struct mii_bus *mii_bus) ++{ ++ int i, nRet1, nRet2; ++ u16 data1 = 0, data2 = 0; ++ struct phy_device *phy_dev; ++ struct ccb_mdiobus_private *bus_priv = mii_bus->priv; ++ struct iproc_mdiobus_data *bus_data = &bus_priv->bus_data; ++ ++ dev_info(mii_bus->parent, "%s : %s phy bus num[%d], type[%d]\n", ++ __func__, mii_bus->id, bus_data->phybus_num, bus_data->phybus_type); ++ ++ /* Check if mdiobus_read works fine */ ++ for (i = 0; i < PHY_MAX_ADDR; i++) { ++ phy_dev = mii_bus->phy_map[i]; ++ if (phy_dev) { ++ dev_info(mii_bus->parent, "phy[%d] id=0x%08x, addr = %d\n", ++ i, phy_dev->phy_id, phy_dev->addr); ++ nRet1 = phy_read(phy_dev, 2); ++ nRet2 = phy_read(phy_dev, 3); ++ if ((nRet1 < 0) || (nRet2 < 0)) { ++ dev_info(mii_bus->parent, ++ "phy_read failed!, %s, nRet1 = %d, nRet2 = %d\n", ++ dev_name(&phy_dev->dev), nRet1, nRet2); ++ } else { ++ dev_info(mii_bus->parent, ++ "%s: reg2 = 0x%x, reg3 = 0x%x\n", ++ dev_name(&phy_dev->dev), nRet1, nRet2); ++ } ++ } ++ } ++ ++ /* Check if general interface function for mdiobus read works fine */ ++ for (i = 0; i < PHY_MAX_ADDR; i++) { ++ data1 = mii_bus->read(mii_bus, i, 2); ++ data2 = mii_bus->read(mii_bus, i, 3); ++ if ((data1 < 0) || (data2 < 0)) { ++ dev_info(mii_bus->parent, ++ "iproc_mdiobus_read failed!, %s phy bus num[%d], type[%d], phyaddr = %d, nRet1 = %d, nRet2 = %d\n", ++ mii_bus->id, bus_data->phybus_num, bus_data->phybus_type, i, data1, data2); ++ } else { ++ dev_info(mii_bus->parent, ++ "read %s phy bus num[%d] type[%d] phyaddr[%d], reg2 = 0x%x, reg3 = 0x%x\n", ++ mii_bus->id, bus_data->phybus_num, bus_data->phybus_type, i, data1, data2); ++ } ++ } ++} ++ ++static struct ccb_mdio_ctrl *ccb_mdio_res_alloc(void) ++{ ++ if (!ccb_mdio) { ++ ccb_mdio = kzalloc(sizeof(*ccb_mdio), GFP_KERNEL); ++ if (!ccb_mdio) { ++ return NULL; ++ } ++ ccb_mdio->ref_cnt = 1; ++ } else { ++ ccb_mdio->ref_cnt++; ++ } ++ ++ return ccb_mdio; ++} ++ ++static void ccb_mdio_res_free(struct ccb_mdio_ctrl *ctrl) ++{ ++ if (ctrl) { ++ ctrl->ref_cnt --; ++ if (ctrl->ref_cnt == 0) { ++ iounmap(ctrl->base); ++ kfree(ctrl); ++ ccb_mdio = NULL; ++ } ++ } ++} ++ ++void ++ccb_mii_init(struct ccb_mdio_ctrl *ccb_mii) ++{ ++ if (ccb_mii->ref_cnt == 1) { ++ /* Set preamble */ ++ W_REG(MII_MGMT, MII_MGMT_PRE_MASK); ++ ++ /* Set the MII default clock 1MHz */ ++ ccb_mii_freq_set(1000); /* KHZ */ ++ } ++} ++ ++#ifdef CONFIG_OF_MDIO ++static int __devinit ccb_mii_probe(struct platform_device *pdev) ++{ ++ int ret = -ENODEV; ++ struct device_node *dn = pdev->dev.of_node; ++ struct mii_bus *mii_bus; ++ struct ccb_mdiobus_private *bus_priv; ++ struct iproc_mdiobus_data *bus_data; ++ u32 mdio_bus_id; ++ const char *mdio_bus_type; ++ struct ccb_mdio_ctrl *ccb_ctrl; ++ struct clk *clk=NULL; ++ ++ if (!of_device_is_available(dn)) ++ return -ENODEV; ++ ++ ccb_ctrl = ccb_mdio_res_alloc(); ++ if (!ccb_ctrl) { ++ printk(KERN_ERR "ccb mdio res alloc failed\n"); ++ return -ENOMEM; ++ ++ } ++ ++ /* Get register base address */ ++ ccb_ctrl->base = (void *)of_iomap(dn, 0); ++ MII_DBG(("MDIO INIT: Base Addr %x\n", ccb_ctrl->base)); ++ ++ clk = of_clk_get (dn, 0); ++ if (clk) ++ ccb_mdio_clk_rate = clk_get_rate(clk)/2; /* used by ccb_mii_freq_set() */ ++ else { ++ printk("No CCB MDIO Clock available from DT, use default clock rate: 62.5MHz\n"); ++ ccb_mdio_clk_rate = 62500000; ++ } ++ ++ ccb_mii_init(ccb_ctrl); ++ ++ if (of_property_read_u32(dn, "#bus-id", &mdio_bus_id)) { ++ mdio_bus_id = 0; /* no property available, use default: 0 */ ++ } ++ if (of_property_read_string(dn, "bus-type", &mdio_bus_type)) { ++ mdio_bus_type = "internal"; /* no property available, use default: "internal" */ ++ } ++ iproc_mdiobus_data.phybus_num = (u8) mdio_bus_id; ++ if (!strcmp(mdio_bus_type, "internal")) ++ iproc_mdiobus_data.phybus_type = IPROC_MDIOBUS_TYPE_INTERNAL; ++ else ++ iproc_mdiobus_data.phybus_type = IPROC_MDIOBUS_TYPE_EXTERNAL; ++ /* Note: this applies to CCB/CCG MDIO, but not for CMICD MDIO */ ++ iproc_mdiobus_data.logbus_num = iproc_mdiobus_data.phybus_num; ++ iproc_mdiobus_data.logbus_type = iproc_mdiobus_data.phybus_type; ++ ++ bus_data = &iproc_mdiobus_data; ++ ++ mii_bus = mdiobus_alloc_size(sizeof(*bus_priv)); ++ if (!mii_bus) ++ return -ENOMEM; ++ ++ mii_bus->name = "iproc_ccb_mdiobus"; ++ snprintf(mii_bus->id, MII_BUS_ID_SIZE, IPROC_MDIO_ID_FMT, ++ bus_data->logbus_num, bus_data->logbus_type); ++ mii_bus->parent = &pdev->dev; ++ mii_bus->read = ccb_mdiobus_read; ++ mii_bus->write = ccb_mdiobus_write; ++ ++ bus_priv = mii_bus->priv; ++ memcpy(&bus_priv->bus_data, bus_data, sizeof(struct iproc_mdiobus_data)); ++ bus_priv->hw_ctrl = ccb_ctrl; ++ ++ ret = mdiobus_register(mii_bus); ++ if (ret) { ++ dev_err(&pdev->dev, "mdiobus_register failed\n"); ++ goto err_exit; ++ } ++ ++ platform_set_drvdata(pdev, mii_bus); ++ ++ /* ccb_mdiobus_test(mii_bus); */ ++ ++ return 0; ++ ++err_exit: ++ kfree(mii_bus); ++ return ret; ++} ++ ++int ccb_mii_remove(struct platform_device *pdev) ++{ ++ struct mii_bus *mii_bus = platform_get_drvdata(pdev); ++ struct ccb_mdiobus_private *bus_priv; ++ ++ if (mii_bus) { ++ bus_priv = mii_bus->priv; ++ ++ mdiobus_unregister(mii_bus); ++ if (bus_priv) { ++ ccb_mdio_res_free(bus_priv->hw_ctrl); ++ } ++ mdiobus_free(mii_bus); ++ } ++ ++ return 0; ++} ++ ++ ++static const struct of_device_id bcm_iproc_dt_ids[] = { ++ { .compatible = "brcm,iproc-ccb-mdio"}, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, bcm_iproc_dt_ids); ++ ++static struct platform_driver iproc_ccb_mdiobus_driver = { ++ .probe = ccb_mii_probe, ++ .remove = ccb_mii_remove, ++ .driver = { ++ .name = DRIVER_NAME, ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(bcm_iproc_dt_ids), ++ }, ++}; ++/*module_platform_driver(iproc_ccb_mdiobus_driver);*/ ++ ++#else /* CONFIG_OF_MDIO */ ++ ++static int __devinit ccb_mdiobus_probe(struct platform_device *pdev) ++{ ++ struct mii_bus *mii_bus; ++ struct ccb_mdiobus_private *bus_priv; ++ struct iproc_mdiobus_data *bus_data = pdev->dev.platform_data; ++ struct ccb_mdio_ctrl *ccb_ctrl; ++ int ret; ++ ++ /* Get register base address */ ++ ccb_ctrl = ccb_mdio_res_alloc(); ++ if (!ccb_ctrl) { ++ printk(KERN_ERR "ccb mdio res alloc failed\n"); ++ ret = -ENOMEM; ++ goto error_exit; ++ } ++ ++ ccb_mii_init(ccb_ctrl); ++ ++ mii_bus = mdiobus_alloc_size(sizeof(*bus_priv)); ++ if (!mii_bus) { ++ dev_err(&pdev->dev, "mdiobus alloc filed\n"); ++ ret = -ENOMEM; ++ goto error_free_ctrl; ++ } ++ ++ mii_bus->name = "iproc_ccb_mdiobus"; ++ snprintf(mii_bus->id, MII_BUS_ID_SIZE, IPROC_MDIO_ID_FMT, ++ bus_data->logbus_num, bus_data->logbus_type); ++ mii_bus->parent = &pdev->dev; ++ mii_bus->read = ccb_mdiobus_read; ++ mii_bus->write = ccb_mdiobus_write; ++ ++ bus_priv = mii_bus->priv; ++ memcpy(&bus_priv->bus_data, bus_data, sizeof(struct iproc_mdiobus_data)); ++ bus_priv->hw_ctrl = ccb_ctrl; ++ ++ ret = mdiobus_register(mii_bus); ++ if (ret) { ++ dev_err(&pdev->dev, "mdiobus_register failed\n"); ++ goto error_free_bus; ++ } ++ ++ platform_set_drvdata(pdev, mii_bus); ++ ++ return 0; ++ ++error_free_bus: ++ kfree(mii_bus); ++error_free_ctrl: ++ ccb_mdio_res_free(ccb_ctrl); ++error_exit: ++ return ret; ++} ++ ++static int __devexit ccb_mdiobus_remove(struct platform_device *pdev) ++{ ++ struct mii_bus *mii_bus = platform_get_drvdata(pdev); ++ struct ccb_mdiobus_private *bus_priv; ++ ++ if (mii_bus) { ++ bus_priv = mii_bus->priv; ++ ++ mdiobus_unregister(mii_bus); ++ if (bus_priv) { ++ ccb_mdio_res_free(bus_priv->hw_ctrl); ++ } ++ mdiobus_free(mii_bus); ++ } ++ ++ return 0; ++} ++ ++static struct platform_driver iproc_ccb_mdiobus_driver = ++{ ++ .driver = { ++ .name = "iproc_ccb_mdio", ++ .owner = THIS_MODULE, ++ }, ++ .probe = ccb_mdiobus_probe, ++ .remove = ccb_mdiobus_remove, ++}; ++#endif /* CONFIG_OF_MDIO */ ++ ++int ++ccb_mdio_init(void) ++{ ++ int ret = -ENODEV; ++ dev_t mdio_dev; ++ mdio_info_t *mdio = NULL; ++ ++ ret = _mdio_handler_init(); ++ if(ret != 0) { ++ ret = -ENOMEM; ++ goto error_exit; ++ } ++ ++ mdio = mdio_devices.mdio; ++ ++ if (mdio_major) { ++ mdio_dev = MKDEV(mdio_major, 0); ++ ret = register_chrdev_region(mdio_dev, 1, "mdio"); ++ } else { ++ ret = alloc_chrdev_region(&mdio_dev, 0, 1, "mdio"); ++ mdio_major = MAJOR(mdio_dev); ++ } ++ if (ret) { ++ goto error_exit; ++ } ++ ++ cdev_init(&mdio_cdev, &mdio_fops); ++ ret = cdev_add(&mdio_cdev, mdio_dev, 1); ++ if (ret) { ++ printk(KERN_ERR "Fail to add mdio char dev!\n"); ++ goto error_region; ++ } ++ ++ platform_driver_register(&iproc_ccb_mdiobus_driver); ++ ++ return 0; ++ ++error_region: ++ unregister_chrdev_region(mdio_dev, 1); ++error_exit: ++ kfree(mdio); ++ return ret; ++} ++ ++void ++ccb_mdio_exit(void) ++{ ++ mdio_info_t *mdio = NULL; ++ ++ mdio = mdio_devices.mdio; ++ kfree(mdio); ++ ++ mdio_devices.mdio = NULL; ++ mdio_devices.init = 0; ++ unregister_chrdev_region(MKDEV(mdio_major, 0), 1); ++ ++ platform_driver_unregister(&iproc_ccb_mdiobus_driver); ++} ++ ++ ++//module_init(ccb_mdio_init); ++subsys_initcall(ccb_mdio_init); ++module_exit(ccb_mdio_exit); ++ ++ ++EXPORT_SYMBOL(ccb_mii_init); ++EXPORT_SYMBOL(ccb_mii_freq_set); ++EXPORT_SYMBOL(ccb_mii_read); ++EXPORT_SYMBOL(ccb_mii_write); ++ ++MODULE_AUTHOR("Broadcom"); ++MODULE_DESCRIPTION("BCM5301X MDIO Device Driver"); ++MODULE_LICENSE("GPL"); ++ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/mdio/ccg_mdio.c b/drivers/net/ethernet/broadcom/mdio/ccg_mdio.c +--- a/drivers/net/ethernet/broadcom/mdio/ccg_mdio.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/mdio/ccg_mdio.c 2017-11-09 17:53:44.080295000 +0800 +@@ -0,0 +1,488 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ */ ++ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "iproc_mdio.h" ++ ++#include ++#include ++#include ++#include ++ ++static struct iproc_mdiobus_data iproc_mdiobus_data; ++/*#define CCG_MDIO_BASE_ADDRESS IPROC_MII_MGMT_CTL*/ ++ ++#define MGMT_CTL_REG 0x000 ++#define MGMT_CTL__BYP_SHIFT 10 ++#define MGMT_CTL__BYP_WIDTH 1 ++#define MGMT_CTL__BYP_MASK ((1 << MGMT_CTL__BYP_WIDTH) - 1) ++#define MGMT_CTL__EXT_SHIFT 9 ++#define MGMT_CTL__EXT_WIDTH 1 ++#define MGMT_CTL__EXT_MASK ((1 << MGMT_CTL__EXT_WIDTH) - 1) ++#define MGMT_CTL__BSY_SHIFT 8 ++#define MGMT_CTL__BSY_WIDTH 1 ++#define MGMT_CTL__BSY_MASK ((1 << MGMT_CTL__BSY_WIDTH) - 1) ++#define MGMT_CTL__PRE_SHIFT 7 ++#define MGMT_CTL__PRE_WIDTH 1 ++#define MGMT_CTL__PRE_MASK ((1 << MGMT_CTL__BSY_WIDTH) - 1) ++#define MGMT_CTL__MDCDIV_SHIFT 0 ++#define MGMT_CTL__MDCDIV_WIDTH 7 ++#define MGMT_CTL__MDCDIV_MASK ((1 << MGMT_CTL__MDCDIV_WIDTH) - 1) ++ ++#define MGMT_CMD_DATA_REG 0x004 ++#define MGMT_CMD_DATA__SB_SHIFT 30 ++#define MGMT_CMD_DATA__SB_WIDTH 2 ++#define MGMT_CMD_DATA__SB_MASK ((1 << MGMT_CMD_DATA__SB_WIDTH) - 1) ++#define MGMT_CMD_DATA__OP_SHIFT 28 ++#define MGMT_CMD_DATA__OP_WIDTH 2 ++#define MGMT_CMD_DATA__OP_MASK ((1 << MGMT_CMD_DATA__OP_WIDTH) - 1) ++#define MGMT_CMD_DATA__PA_SHIFT 23 ++#define MGMT_CMD_DATA__PA_WIDTH 5 ++#define MGMT_CMD_DATA__PA_MASK ((1 << MGMT_CMD_DATA__PA_WIDTH) - 1) ++#define MGMT_CMD_DATA__RA_SHIFT 18 ++#define MGMT_CMD_DATA__RA_WIDTH 5 ++#define MGMT_CMD_DATA__RA_MASK ((1 << MGMT_CMD_DATA__RA_WIDTH) - 1) ++#define MGMT_CMD_DATA__TA_SHIFT 16 ++#define MGMT_CMD_DATA__TA_WIDTH 2 ++#define MGMT_CMD_DATA__TA_MASK ((1 << MGMT_CMD_DATA__TA_WIDTH) - 1) ++#define MGMT_CMD_DATA__DATA_SHIFT 0 ++#define MGMT_CMD_DATA__DATA_WIDTH 16 ++#define MGMT_CMD_DATA__DATA_MASK ((1 << MGMT_CMD_DATA__DATA_WIDTH) - 1) ++ ++ ++#define SET_REG_FIELD(reg_value, fshift, fmask, fvalue) \ ++ (reg_value) = ((reg_value) & ~((fmask) << (fshift))) | \ ++ (((fvalue) & (fmask)) << (fshift)) ++#define ISET_REG_FIELD(reg_value, fshift, fmask, fvalue) \ ++ (reg_value) = (reg_value) | (((fvalue) & (fmask)) << (fshift)) ++#define GET_REG_FIELD(reg_value, fshift, fmask) \ ++ (((reg_value) & ((fmask) << (fshift))) >> (fshift)) ++ ++#define MII_OP_MAX_HALT_USEC 500 ++#define MII_OP_HALT_USEC 10 ++ ++enum { ++ MII_OP_MODE_READ, ++ MII_OP_MODE_WRITE, ++ MII_OP_MODE_MAX ++}; ++ ++/** ++ * struct cmicd_mdio: cmicd mdio structure ++ * @resource: resource of cmicd cmc2 ++ * @base: base address of cmicd cmc2 ++ * @lock: spin lock protecting io access ++ */ ++struct ccg_mdio_ctrl { ++ void __iomem *base; ++ /* Use spinlock to co-operate that the caller might be in interrupt context */ ++ /* struct mutex lock; */ ++ spinlock_t lock; ++ int ref_cnt; ++}; ++ ++struct ccg_mdiobus_private { ++ /* iproc_mdiobus_data field have to be placed at the beginning of ++ * mdiobus private data */ ++ struct iproc_mdiobus_data bus_data; ++ struct ccg_mdio_ctrl *hw_ctrl; ++}; ++ ++struct ccg_mii_cmd { ++ int bus_id; ++ int ext_sel; ++ int phy_id; ++ int regnum; ++ u16 op_mode; ++ u16 val; ++}; ++ ++static struct ccg_mdio_ctrl *ccg_mdio = NULL; ++static uint32_t ccg_mdio_clk_rate; ++ ++ ++static void __maybe_unused ccg_mdiobus_test(struct mii_bus *mii_bus) ++{ ++ int i; ++ u16 data1 = 0, data2 = 0; ++ struct phy_device *phy_dev; ++ struct ccg_mdiobus_private *bus_priv = mii_bus->priv; ++ struct iproc_mdiobus_data *bus_data = &bus_priv->bus_data; ++ ++ dev_info(mii_bus->parent, "%s : %s phy bus num[%d], type[%d]\n", ++ __func__, mii_bus->id, bus_data->phybus_num, bus_data->phybus_type); ++ ++ /* Check if mdiobus_read works fine */ ++ for (i = 0; i < PHY_MAX_ADDR; i++) { ++ phy_dev = mii_bus->phy_map[i]; ++ if (phy_dev) ++ dev_info(mii_bus->parent, "phy[%d] id=0x%08x, addr = %d\n", ++ i, phy_dev->phy_id, phy_dev->addr); ++ } ++ ++ /* Check if general interface function for mdiobus read works fine */ ++ for (i = 0; i < PHY_MAX_ADDR; i++) { ++ data1 = mii_bus->read(mii_bus, i, 2); ++ data2 = mii_bus->read(mii_bus, i, 3); ++ if ((data1 < 0) || (data2 < 0)) { ++ dev_info(mii_bus->parent, ++ "iproc_mdiobus_read failed!, %s phy bus num[%d], type[%d], phyaddr = %d, nRet1 = %d, nRet2 = %d\n", ++ mii_bus->id, bus_data->phybus_num, bus_data->phybus_type, i, data1, data2); ++ } else { ++ dev_info(mii_bus->parent, ++ "read %s phy bus num[%d] type[%d] phyaddr[%d], reg2 = 0x%x, reg3 = 0x%x\n", ++ mii_bus->id, bus_data->phybus_num, bus_data->phybus_type, i, data1, data2); ++ } ++ } ++ ++} ++ ++static inline u32 ccg_mii_reg_read(struct ccg_mdio_ctrl *ccg_mii, u32 reg) ++{ ++ return readl(ccg_mii->base + reg); ++} ++ ++static inline void ccg_mii_reg_write(struct ccg_mdio_ctrl *ccg_mii, u32 reg, u32 data) ++{ ++ writel(data, ccg_mii->base + reg); ++} ++ ++static inline int ccg_mii_busy(struct ccg_mdio_ctrl *ccg_mii, int to_usec) ++{ ++ do { ++ if(!GET_REG_FIELD(ccg_mii_reg_read(ccg_mii, MGMT_CTL_REG), ++ MGMT_CTL__BSY_SHIFT, MGMT_CTL__BSY_MASK)) ++ return 0; ++ udelay(MII_OP_HALT_USEC); ++ to_usec -= MII_OP_HALT_USEC; ++ } while (to_usec > 0); ++ ++ return 1; ++} ++ ++static int do_ccg_mii_op(struct ccg_mdio_ctrl *ccg_mii, struct ccg_mii_cmd *cmd) ++{ ++ u32 cmd_data = 0, mgt_ctrl; ++ unsigned long flags; ++ int ret = 0; ++ ++ if (MII_OP_MODE_WRITE == cmd->op_mode) { ++ ISET_REG_FIELD(cmd_data, MGMT_CMD_DATA__OP_SHIFT, ++ MGMT_CMD_DATA__OP_MASK, 1); ++ ISET_REG_FIELD(cmd_data, MGMT_CMD_DATA__DATA_SHIFT, ++ MGMT_CMD_DATA__DATA_MASK, cmd->val); ++ } ++ else if (MII_OP_MODE_READ == cmd->op_mode) { ++ ISET_REG_FIELD(cmd_data, MGMT_CMD_DATA__OP_SHIFT, ++ MGMT_CMD_DATA__OP_MASK, 2); ++ } ++ else { ++ printk(KERN_ERR "%s : invald operation %d\n", __func__, cmd->op_mode); ++ return -EINVAL; ++ } ++ ++ ISET_REG_FIELD(cmd_data, MGMT_CMD_DATA__PA_SHIFT, ++ MGMT_CMD_DATA__PA_MASK, cmd->phy_id); ++ ISET_REG_FIELD(cmd_data, MGMT_CMD_DATA__RA_SHIFT, ++ MGMT_CMD_DATA__RA_MASK, cmd->regnum); ++ ISET_REG_FIELD(cmd_data, MGMT_CMD_DATA__TA_SHIFT, ++ MGMT_CMD_DATA__TA_MASK, 2); ++ ISET_REG_FIELD(cmd_data, MGMT_CMD_DATA__SB_SHIFT, ++ MGMT_CMD_DATA__SB_MASK, 1); ++ ++ /* mutex_lock(&ccg_mii->lock); */ ++ spin_lock_irqsave(&ccg_mii->lock, flags); ++ ++ if (ccg_mii_busy(ccg_mii, MII_OP_MAX_HALT_USEC)) { ++ ret = -EBUSY; ++ printk(KERN_ERR "%s : bus busy (1)\n", __func__); ++ goto err_exit_unlock; ++ } ++ ++ mgt_ctrl = ccg_mii_reg_read(ccg_mii, MGMT_CTL_REG); ++ if (cmd->ext_sel != GET_REG_FIELD(mgt_ctrl, MGMT_CTL__EXT_SHIFT, ++ MGMT_CTL__EXT_MASK)) { ++ SET_REG_FIELD(mgt_ctrl, MGMT_CTL__EXT_SHIFT, MGMT_CTL__EXT_MASK, cmd->ext_sel); ++ ccg_mii_reg_write(ccg_mii, MGMT_CTL_REG, mgt_ctrl); ++ } ++ ++ ccg_mii_reg_write(ccg_mii, MGMT_CMD_DATA_REG, cmd_data); ++ ++ if (ccg_mii_busy(ccg_mii, MII_OP_MAX_HALT_USEC)) { ++ ret = -EBUSY; ++ printk(KERN_ERR "%s : bus busy (2)\n", __func__); ++ goto err_exit_unlock; ++ } ++ ++ if (MII_OP_MODE_READ == cmd->op_mode) { ++ ret = GET_REG_FIELD(ccg_mii_reg_read(ccg_mii, MGMT_CMD_DATA_REG), ++ MGMT_CMD_DATA__DATA_SHIFT, MGMT_CMD_DATA__DATA_MASK); ++ } ++ ++ /* mutex_unlock(&ccg_mii->lock); */ ++ spin_unlock_irqrestore(&ccg_mii->lock, flags); ++ ++ return ret; ++ ++err_exit_unlock: ++ /* mutex_unlock(&ccg_mii->lock); */ ++ spin_unlock_irqrestore(&ccg_mii->lock, flags); ++ return ret; ++} ++ ++static int ccg_mdiobus_read(struct mii_bus *bus, int phy_id, int regnum) ++{ ++ struct ccg_mdiobus_private *bus_priv = bus->priv; ++ struct iproc_mdiobus_data *bus_data = &bus_priv->bus_data; ++ struct ccg_mii_cmd cmd = {0}; ++ ++ cmd.bus_id = bus_data->phybus_num; ++ if (IPROC_MDIOBUS_TYPE_EXTERNAL == bus_data->phybus_type) ++ cmd.ext_sel = 1; ++ cmd.phy_id = phy_id; ++ cmd.regnum = regnum; ++ cmd.op_mode = MII_OP_MODE_READ; ++ ++ return do_ccg_mii_op(bus_priv->hw_ctrl, &cmd); ++} ++ ++static int ccg_mdiobus_write(struct mii_bus *bus, int phy_id, ++ int regnum, u16 val) ++{ ++ struct ccg_mdiobus_private *bus_priv = bus->priv; ++ struct iproc_mdiobus_data *bus_data = &bus_priv->bus_data; ++ struct ccg_mii_cmd cmd = {0}; ++ ++ cmd.bus_id = bus_data->phybus_num; ++ if (IPROC_MDIOBUS_TYPE_EXTERNAL == bus_data->phybus_type) ++ cmd.ext_sel = 1; ++ cmd.phy_id = phy_id; ++ cmd.regnum = regnum; ++ cmd.op_mode = MII_OP_MODE_WRITE; ++ cmd.val = val; ++ ++ return do_ccg_mii_op(bus_priv->hw_ctrl, &cmd); ++} ++ ++static struct ccg_mdio_ctrl * ccg_mdio_res_alloc(void) ++{ ++ if (!ccg_mdio) { ++ ccg_mdio = kzalloc(sizeof(*ccg_mdio), GFP_KERNEL); ++ if (!ccg_mdio) ++ return NULL; ++ ++ /* mutex_init(&ccg_mdio->lock); */ ++ spin_lock_init(&ccg_mdio->lock); ++ ccg_mdio->ref_cnt = 1; ++ } ++ else ++ ccg_mdio->ref_cnt ++; ++ ++ return ccg_mdio; ++} ++ ++static void ccg_mdio_res_free(struct ccg_mdio_ctrl *ctrl) ++{ ++ if (ctrl) { ++ ctrl->ref_cnt --; ++ if (ctrl->ref_cnt == 0) { ++ iounmap(ctrl->base); ++ kfree(ctrl); ++ ccg_mdio = NULL; ++ } ++ } ++} ++ ++static void ccg_mii_init(struct ccg_mdio_ctrl *ccg_mii) ++{ ++ u32 clk_rate, val = 0; ++ ++ if(ccg_mii->ref_cnt == 1) { ++ /* Set preamble enabled */ ++ ISET_REG_FIELD(val, MGMT_CTL__PRE_SHIFT, MGMT_CTL__PRE_MASK, 1); ++ ++ clk_rate = ccg_mdio_clk_rate; ++ ++ /* ++ * MII Mgt Clock (MDC) Divisor. 0x0: Disable output of the MDC ++ * Non-zero: Output the MDC with a frequency that is ++ * PCLK/(2* the value of this field). ++ */ ++ ISET_REG_FIELD(val, MGMT_CTL__MDCDIV_SHIFT, MGMT_CTL__MDCDIV_MASK, ++ clk_rate/(1000000)); /* Set the MII default clock to 1MHz: */ ++ ++ ccg_mii_reg_write(ccg_mii, MGMT_CTL_REG, val); ++ } ++} ++ ++static int ccg_mdiobus_probe(struct platform_device *pdev) ++{ ++ struct mii_bus *mii_bus; ++ struct device_node *dn = pdev->dev.of_node; ++ struct ccg_mdiobus_private *bus_priv; ++ struct iproc_mdiobus_data *bus_data; ++ struct ccg_mdio_ctrl *ccg_ctrl; ++ u32 mdio_bus_id; ++ const char *mdio_bus_type; ++ struct clk *clk=NULL; ++ int ret; ++ ++ if (!of_device_is_available(dn)) ++ return -ENODEV; ++ ++ ccg_ctrl = ccg_mdio_res_alloc(); ++ if (!ccg_ctrl) { ++ dev_err(&pdev->dev, "ccg mdio res alloc failed\n"); ++ ret = -ENOMEM; ++ goto err_exit; ++ } ++ ++ /* Get register base address */ ++ ccg_ctrl->base = (void *)of_iomap(dn, 0); ++ ++ clk = of_clk_get (dn, 0); ++ if (clk) ++ ccg_mdio_clk_rate = clk_get_rate(clk)/2; /* used by ccg_mii_init */ ++ else { ++ printk("No CCG MDIO Clock available from DT, use default clock rate: 50MHz\n"); ++ ccg_mdio_clk_rate = 50000000; ++ } ++ ++ ccg_mii_init(ccg_ctrl); ++ ++ if (of_property_read_u32(dn, "#bus-id", &mdio_bus_id)) ++ mdio_bus_id = 0; /* default: 0 */ ++ ++ if (of_property_read_string(dn, "bus-type", &mdio_bus_type)) ++ mdio_bus_type = "internal"; /* default: "internal" */ ++ ++ iproc_mdiobus_data.phybus_num = (u8) mdio_bus_id; ++ if (!strcmp(mdio_bus_type, "internal")) ++ iproc_mdiobus_data.phybus_type = IPROC_MDIOBUS_TYPE_INTERNAL; ++ else ++ iproc_mdiobus_data.phybus_type = IPROC_MDIOBUS_TYPE_EXTERNAL; ++ ++ /* Note: this applies to CCB/CCG MDIO, but not for CMICD MDIO */ ++ iproc_mdiobus_data.logbus_num = iproc_mdiobus_data.phybus_num; ++ iproc_mdiobus_data.logbus_type = iproc_mdiobus_data.phybus_type; ++ ++ bus_data = &iproc_mdiobus_data; ++ ++ mii_bus = mdiobus_alloc_size(sizeof(*bus_priv)); ++ if (!mii_bus) { ++ dev_err(&pdev->dev, "mdiobus alloc filed\n"); ++ ret = -ENOMEM; ++ goto err_free_ctrl; ++ } ++ ++ mii_bus->name = "iproc_ccg_mdiobus"; ++ snprintf(mii_bus->id, MII_BUS_ID_SIZE, IPROC_MDIO_ID_FMT, ++ bus_data->logbus_num, bus_data->logbus_type); ++ mii_bus->parent = &pdev->dev; ++ mii_bus->read = ccg_mdiobus_read; ++ mii_bus->write = ccg_mdiobus_write; ++ ++ bus_priv = mii_bus->priv; ++ memcpy(&bus_priv->bus_data, bus_data, sizeof(struct iproc_mdiobus_data)); ++ bus_priv->hw_ctrl = ccg_ctrl; ++ ++ if (IS_ENABLED(CONFIG_MACH_GH2) || IS_ENABLED(CONFIG_MACH_WH2)) ++ ret = of_mdiobus_register(mii_bus, dn); ++ else ++ ret = mdiobus_register(mii_bus); ++ ++ if (ret) { ++ dev_err(&pdev->dev, "mdiobus_register failed\n"); ++ goto err_free_bus; ++ } ++ ++ platform_set_drvdata(pdev, mii_bus); ++ ++#if 0 ++ ccg_mdiobus_test(mii_bus); ++#endif ++ ++ return 0; ++ ++err_free_bus: ++ kfree(mii_bus); ++err_free_ctrl: ++ ccg_mdio_res_free(ccg_ctrl); ++err_exit: ++ return ret; ++} ++ ++static int ccg_mdiobus_remove(struct platform_device *pdev) ++{ ++ struct mii_bus *mii_bus = platform_get_drvdata(pdev); ++ struct ccg_mdiobus_private *bus_priv; ++ ++ if (mii_bus) { ++ bus_priv = mii_bus->priv; ++ ++ mdiobus_unregister(mii_bus); ++ if (bus_priv) ++ ccg_mdio_res_free(bus_priv->hw_ctrl); ++ mdiobus_free(mii_bus); ++ } ++ ++ return 0; ++} ++ ++static const struct of_device_id bcm_iproc_dt_ids[] = { ++ { .compatible = "brcm,iproc-ccg-mdio"}, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, bcm_iproc_dt_ids); ++ ++ ++static struct platform_driver iproc_ccg_mdiobus_driver = ++{ ++ .driver = { ++ .name = "iproc_ccg_mdio", ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(bcm_iproc_dt_ids), ++ }, ++ .probe = ccg_mdiobus_probe, ++ .remove = ccg_mdiobus_remove, ++}; ++ ++static int __init ccg_mdio_init(void) ++{ ++ return platform_driver_register(&iproc_ccg_mdiobus_driver); ++} ++ ++static void __exit ccg_mdio_exit(void) ++{ ++ platform_driver_unregister(&iproc_ccg_mdiobus_driver); ++} ++ ++//module_init(ccg_mdio_init); ++subsys_initcall(ccg_mdio_init); ++module_exit(ccg_mdio_exit); ++ ++MODULE_AUTHOR("Broadcom Corporation"); ++MODULE_DESCRIPTION("iProc CCG mdio driver"); ++MODULE_LICENSE("GPL"); ++ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/mdio/cmicd_mdio.c b/drivers/net/ethernet/broadcom/mdio/cmicd_mdio.c +--- a/drivers/net/ethernet/broadcom/mdio/cmicd_mdio.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/mdio/cmicd_mdio.c 2017-11-09 17:53:44.081297000 +0800 +@@ -0,0 +1,606 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "iproc_mdio.h" ++ ++#include ++#include ++#include ++#include ++ ++static struct iproc_mdiobus_data iproc_mdiobus_data; ++ ++/* CMICD MDIO */ ++#define CMIC_COMMON_MIIM_PARAM_OFFSET 0x080 ++#define CMIC_COMMON_MIIM_PARAM__MIIM_CYCLE_L 31 ++#define CMIC_COMMON_MIIM_PARAM__MIIM_CYCLE_R 29 ++#define CMIC_COMMON_MIIM_PARAM__MIIM_CYCLE_WIDTH 3 ++#define CMIC_COMMON_MIIM_PARAM__MIIM_CYCLE_RESETVALUE 0x0 ++#define CMIC_COMMON_MIIM_PARAM__INTERNAL_SEL 25 ++#define CMIC_COMMON_MIIM_PARAM__INTERNAL_SEL_WIDTH 1 ++#define CMIC_COMMON_MIIM_PARAM__INTERNAL_SEL_RESETVALUE 0x0 ++#define CMIC_COMMON_MIIM_PARAM__BUS_ID_L 24 ++#define CMIC_COMMON_MIIM_PARAM__BUS_ID_R 22 ++#define CMIC_COMMON_MIIM_PARAM__BUS_ID_WIDTH 3 ++#define CMIC_COMMON_MIIM_PARAM__BUS_ID_RESETVALUE 0x0 ++#define CMIC_COMMON_MIIM_PARAM__C45_SEL 21 ++#define CMIC_COMMON_MIIM_PARAM__C45_SEL_WIDTH 1 ++#define CMIC_COMMON_MIIM_PARAM__C45_SEL_RESETVALUE 0x0 ++#define CMIC_COMMON_MIIM_PARAM__PHY_ID_L 20 ++#define CMIC_COMMON_MIIM_PARAM__PHY_ID_R 16 ++#define CMIC_COMMON_MIIM_PARAM__PHY_ID_WIDTH 5 ++#define CMIC_COMMON_MIIM_PARAM__PHY_ID_RESETVALUE 0x0 ++#define CMIC_COMMON_MIIM_PARAM__PHY_DATA_L 15 ++#define CMIC_COMMON_MIIM_PARAM__PHY_DATA_R 0 ++#define CMIC_COMMON_MIIM_PARAM__PHY_DATA_WIDTH 16 ++#define CMIC_COMMON_MIIM_PARAM__PHY_DATA_RESETVALUE 0x0000 ++#define CMIC_COMMON_MIIM_PARAM__RESERVED_L 28 ++#define CMIC_COMMON_MIIM_PARAM__RESERVED_R 26 ++#define CMIC_COMMON_MIIM_PARAM_WIDTH 32 ++#define CMIC_COMMON_MIIM_PARAM__WIDTH 32 ++#define CMIC_COMMON_MIIM_PARAM_ALL_L 31 ++#define CMIC_COMMON_MIIM_PARAM_ALL_R 0 ++#define CMIC_COMMON_MIIM_PARAM__ALL_L 31 ++#define CMIC_COMMON_MIIM_PARAM__ALL_R 0 ++#define CMIC_COMMON_MIIM_PARAM_DATAMASK 0xe3ffffff ++#define CMIC_COMMON_MIIM_PARAM_RDWRMASK 0x1c000000 ++#define CMIC_COMMON_MIIM_PARAM_RESETVALUE 0x0 ++ ++#define CMIC_COMMON_MIIM_READ_DATA_OFFSET 0x084 ++#define CMIC_COMMON_MIIM_READ_DATA__DATA_L 15 ++#define CMIC_COMMON_MIIM_READ_DATA__DATA_R 0 ++#define CMIC_COMMON_MIIM_READ_DATA__DATA_WIDTH 16 ++#define CMIC_COMMON_MIIM_READ_DATA__DATA_RESETVALUE 0x0000 ++#define CMIC_COMMON_MIIM_READ_DATA__RESERVED_L 31 ++#define CMIC_COMMON_MIIM_READ_DATA__RESERVED_R 16 ++#define CMIC_COMMON_MIIM_READ_DATA_WIDTH 16 ++#define CMIC_COMMON_MIIM_READ_DATA__WIDTH 16 ++#define CMIC_COMMON_MIIM_READ_DATA_ALL_L 15 ++#define CMIC_COMMON_MIIM_READ_DATA_ALL_R 0 ++#define CMIC_COMMON_MIIM_READ_DATA__ALL_L 15 ++#define CMIC_COMMON_MIIM_READ_DATA__ALL_R 0 ++#define CMIC_COMMON_MIIM_READ_DATA_DATAMASK 0x0000ffff ++#define CMIC_COMMON_MIIM_READ_DATA_RDWRMASK 0xffff0000 ++#define CMIC_COMMON_MIIM_READ_DATA_RESETVALUE 0x0 ++ ++#define CMIC_COMMON_MIIM_ADDRESS_OFFSET 0x088 ++#define CMIC_COMMON_MIIM_ADDRESS__CLAUSE_45_DTYPE_L 20 ++#define CMIC_COMMON_MIIM_ADDRESS__CLAUSE_45_DTYPE_R 16 ++#define CMIC_COMMON_MIIM_ADDRESS__CLAUSE_45_DTYPE_WIDTH 5 ++#define CMIC_COMMON_MIIM_ADDRESS__CLAUSE_45_DTYPE_RESETVALUE 0x0 ++#define CMIC_COMMON_MIIM_ADDRESS__CLAUSE_45_REGADR_L 15 ++#define CMIC_COMMON_MIIM_ADDRESS__CLAUSE_45_REGADR_R 0 ++#define CMIC_COMMON_MIIM_ADDRESS__CLAUSE_45_REGADR_WIDTH 16 ++#define CMIC_COMMON_MIIM_ADDRESS__CLAUSE_45_REGADR_RESETVALUE 0x0000 ++#define CMIC_COMMON_MIIM_ADDRESS__CLAUSE_22_REGADR_L 4 ++#define CMIC_COMMON_MIIM_ADDRESS__CLAUSE_22_REGADR_R 0 ++#define CMIC_COMMON_MIIM_ADDRESS__CLAUSE_22_REGADR_WIDTH 5 ++#define CMIC_COMMON_MIIM_ADDRESS__CLAUSE_22_REGADR_RESETVALUE 0x0 ++#define CMIC_COMMON_MIIM_ADDRESS__RESERVED_L 31 ++#define CMIC_COMMON_MIIM_ADDRESS__RESERVED_R 21 ++#define CMIC_COMMON_MIIM_ADDRESS_WIDTH 21 ++#define CMIC_COMMON_MIIM_ADDRESS__WIDTH 21 ++#define CMIC_COMMON_MIIM_ADDRESS_ALL_L 20 ++#define CMIC_COMMON_MIIM_ADDRESS_ALL_R 0 ++#define CMIC_COMMON_MIIM_ADDRESS__ALL_L 20 ++#define CMIC_COMMON_MIIM_ADDRESS__ALL_R 0 ++#define CMIC_COMMON_MIIM_ADDRESS_DATAMASK 0x001fffff ++#define CMIC_COMMON_MIIM_ADDRESS_RDWRMASK 0xffe00000 ++#define CMIC_COMMON_MIIM_ADDRESS_RESETVALUE 0x0 ++ ++#define CMIC_COMMON_MIIM_CTRL_OFFSET 0x08c ++#define CMIC_COMMON_MIIM_CTRL__MIIM_RD_START 1 ++#define CMIC_COMMON_MIIM_CTRL__MIIM_RD_START_WIDTH 1 ++#define CMIC_COMMON_MIIM_CTRL__MIIM_RD_START_RESETVALUE 0x0 ++#define CMIC_COMMON_MIIM_CTRL__MIIM_WR_START 0 ++#define CMIC_COMMON_MIIM_CTRL__MIIM_WR_START_WIDTH 1 ++#define CMIC_COMMON_MIIM_CTRL__MIIM_WR_START_RESETVALUE 0x0 ++#define CMIC_COMMON_MIIM_CTRL__RESERVED_L 31 ++#define CMIC_COMMON_MIIM_CTRL__RESERVED_R 2 ++#define CMIC_COMMON_MIIM_CTRL_WIDTH 2 ++#define CMIC_COMMON_MIIM_CTRL__WIDTH 2 ++#define CMIC_COMMON_MIIM_CTRL_ALL_L 1 ++#define CMIC_COMMON_MIIM_CTRL_ALL_R 0 ++#define CMIC_COMMON_MIIM_CTRL__ALL_L 1 ++#define CMIC_COMMON_MIIM_CTRL__ALL_R 0 ++#define CMIC_COMMON_MIIM_CTRL_DATAMASK 0x00000003 ++#define CMIC_COMMON_MIIM_CTRL_RDWRMASK 0xfffffffc ++#define CMIC_COMMON_MIIM_CTRL_RESETVALUE 0x0 ++ ++#define CMIC_COMMON_MIIM_STAT_OFFSET 0x090 ++#define CMIC_COMMON_MIIM_STAT__MIIM_OPN_DONE 0 ++#define CMIC_COMMON_MIIM_STAT__MIIM_OPN_DONE_WIDTH 1 ++#define CMIC_COMMON_MIIM_STAT__MIIM_OPN_DONE_RESETVALUE 0x0 ++#define CMIC_COMMON_MIIM_STAT__RESERVED_L 31 ++#define CMIC_COMMON_MIIM_STAT__RESERVED_R 1 ++#define CMIC_COMMON_MIIM_STAT_WIDTH 1 ++#define CMIC_COMMON_MIIM_STAT__WIDTH 1 ++#define CMIC_COMMON_MIIM_STAT_ALL_L 0 ++#define CMIC_COMMON_MIIM_STAT_ALL_R 0 ++#define CMIC_COMMON_MIIM_STAT__ALL_L 0 ++#define CMIC_COMMON_MIIM_STAT__ALL_R 0 ++#define CMIC_COMMON_MIIM_STAT_DATAMASK 0x00000001 ++#define CMIC_COMMON_MIIM_STAT_RDWRMASK 0xfffffffe ++#define CMIC_COMMON_MIIM_STAT_RESETVALUE 0x0 ++ ++#define CMIC_COMMON_UC0_PIO_ENDIANESS 0x1F0 ++ ++#define MIIM_PARAM_REG CMIC_COMMON_MIIM_PARAM_OFFSET ++#define MIIM_PARAM__MIIM_CYCLE_SHIFT CMIC_COMMON_MIIM_PARAM__MIIM_CYCLE_R ++#define MIIM_PARAM__MIIM_CYCLE_MASK ((1 << CMIC_COMMON_MIIM_PARAM__MIIM_CYCLE_WIDTH) - 1) ++#define MIIM_PARAM__INTERNAL_SEL_SHIFT CMIC_COMMON_MIIM_PARAM__INTERNAL_SEL ++#define MIIM_PARAM__INTERNAL_SEL_MASK ((1 << CMIC_COMMON_MIIM_PARAM__INTERNAL_SEL_WIDTH) - 1) ++#define MIIM_PARAM__BUS_ID_SHIFT CMIC_COMMON_MIIM_PARAM__BUS_ID_R ++#define MIIM_PARAM__BUS_ID_MASK ((1 << CMIC_COMMON_MIIM_PARAM__BUS_ID_WIDTH) - 1) ++#define MIIM_PARAM__C45_SEL_SHIFT CMIC_COMMON_MIIM_PARAM__C45_SEL ++#define MIIM_PARAM__C45_SEL_MASK ((1 << CMIC_COMMON_MIIM_PARAM__C45_SEL_WIDTH) - 1) ++#define MIIM_PARAM__PHY_ID_SHIFT CMIC_COMMON_MIIM_PARAM__PHY_ID_R ++#define MIIM_PARAM__PHY_ID_MASK ((1 << CMIC_COMMON_MIIM_PARAM__PHY_ID_WIDTH) - 1) ++#define MIIM_PARAM__PHY_DATA_SHIFT CMIC_COMMON_MIIM_PARAM__PHY_DATA_R ++#define MIIM_PARAM__PHY_DATA_MASK ((1 << CMIC_COMMON_MIIM_PARAM__PHY_DATA_WIDTH) - 1) ++ ++#define MIIM_READ_DATA_REG CMIC_COMMON_MIIM_READ_DATA_OFFSET ++#define MIIM_READ_DATA__DATA_SHIFT CMIC_COMMON_MIIM_READ_DATA__DATA_R ++#define MIIM_READ_DATA__DATA_MASK ((1 << CMIC_COMMON_MIIM_READ_DATA__DATA_WIDTH) - 1) ++ ++#define MIIM_ADDRESS_REG CMIC_COMMON_MIIM_ADDRESS_OFFSET ++#define MIIM_ADDRESS__CLAUSE_45_DTYPE_SHIFT CMIC_COMMON_MIIM_ADDRESS__CLAUSE_45_DTYPE_R ++#define MIIM_ADDRESS__CLAUSE_45_DTYPE_MASK ((1 << CMIC_COMMON_MIIM_ADDRESS__CLAUSE_45_DTYPE_WIDTH) - 1) ++#define MIIM_ADDRESS__CLAUSE_45_REGADR_SHIFT CMIC_COMMON_MIIM_ADDRESS__CLAUSE_45_REGADR_R ++#define MIIM_ADDRESS__CLAUSE_45_REGADR_MASK ((1 << CMIC_COMMON_MIIM_ADDRESS__CLAUSE_45_REGADR_WIDTH) - 1) ++#define MIIM_ADDRESS__CLAUSE_22_REGADR_SHIFT CMIC_COMMON_MIIM_ADDRESS__CLAUSE_22_REGADR_R ++#define MIIM_ADDRESS__CLAUSE_22_REGADR_MASK ((1 << CMIC_COMMON_MIIM_ADDRESS__CLAUSE_22_REGADR_WIDTH) - 1) ++ ++#define MIIM_CTRL_REG CMIC_COMMON_MIIM_CTRL_OFFSET ++#define MIIM_CTRL__MIIM_RD_START_SHIFT CMIC_COMMON_MIIM_CTRL__MIIM_RD_START ++#define MIIM_CTRL__MIIM_RD_START_MASK ((1 << CMIC_COMMON_MIIM_CTRL__MIIM_RD_START_WIDTH) - 1) ++#define MIIM_CTRL__MIIM_WR_START_SHIFT CMIC_COMMON_MIIM_CTRL__MIIM_WR_START ++#define MIIM_CTRL__MIIM_WR_START_MASK ((1 << CMIC_COMMON_MIIM_CTRL__MIIM_WR_START_WIDTH) - 1) ++ ++#define MIIM_STAT_REG CMIC_COMMON_MIIM_STAT_OFFSET ++#define MIIM_STAT__MIIM_OPN_DONE_SHIFT CMIC_COMMON_MIIM_STAT__MIIM_OPN_DONE ++#define MIIM_STAT__MIIM_OPN_DONE_MASK ((1 << CMIC_COMMON_MIIM_STAT__MIIM_OPN_DONE_WIDTH) - 1) ++ ++#define SET_REG_FIELD(reg_value, fshift, fmask, fvalue) \ ++ (reg_value) = ((reg_value) & ~((fmask) << (fshift))) | \ ++ (((fvalue) & (fmask)) << (fshift)) ++#define ISET_REG_FIELD(reg_value, fshift, fmask, fvalue) \ ++ (reg_value) = (reg_value) | (((fvalue) & (fmask)) << (fshift)) ++#define GET_REG_FIELD(reg_value, fshift, fmask) \ ++ (((reg_value) & ((fmask) << (fshift))) >> (fshift)) ++ ++#define MIIM_OP_MAX_HALT_USEC 500 ++ ++enum { ++ MIIM_OP_MODE_READ, ++ MIIM_OP_MODE_WRITE, ++ MIIM_OP_MODE_MAX ++}; ++ ++/** ++ * struct cmicd_mdio: cmicd mdio structure ++ * @base: base address of cmic_common ++ * @lock: spin lock protecting io access ++ */ ++struct cmicd_mdio_ctrl { ++ void __iomem *base; ++ /* Use spinlock to co-operate that the caller might be in interrupt context */ ++ /* struct mutex lock; */ ++ spinlock_t lock; ++ int ref_cnt; ++}; ++ ++struct cmicd_mdiobus_private { ++ /* iproc_mdiobus_data field have to be placed at the beginning of ++ * mdiobus private data */ ++ struct iproc_mdiobus_data bus_data; ++ struct cmicd_mdio_ctrl *hw_ctrl; ++}; ++ ++struct cmicd_miim_cmd { ++ int bus_id; ++ int int_sel; ++ int phy_id; ++ int regnum; ++ int c45_sel; ++ u16 op_mode; ++ u16 val; ++}; ++ ++static struct cmicd_mdio_ctrl *cmic_common = NULL; ++ ++ ++static void __maybe_unused cmicd_mdiobus_test(struct mii_bus *mii_bus) ++{ ++ int i; ++ u16 data1 = 0, data2 = 0; ++ struct phy_device *phy_dev; ++ struct cmicd_mdiobus_private *bus_priv = mii_bus->priv; ++ struct iproc_mdiobus_data *bus_data = &bus_priv->bus_data; ++ ++ dev_info(mii_bus->parent, "%s : %s phy bus num[%d], type[%d]\n", ++ __func__, mii_bus->id, bus_data->phybus_num, bus_data->phybus_type); ++ ++ /* Check if mdiobus_read works fine */ ++ for (i = 0; i < PHY_MAX_ADDR; i++) { ++ phy_dev = mii_bus->phy_map[i]; ++ if (phy_dev) ++ dev_info(mii_bus->parent, "phy[%d] id=0x%08x, addr = %d\n", ++ i, phy_dev->phy_id, phy_dev->addr); ++ } ++ ++ /* Check if general interface function for mdiobus read works fine */ ++ for (i = 0; i < PHY_MAX_ADDR; i++) { ++ data1 = mii_bus->read(mii_bus, i, 2); ++ data2 = mii_bus->read(mii_bus, i, 3); ++ if ((data1 < 0) || (data2 < 0)) { ++ dev_info(mii_bus->parent, ++ "iproc_mdiobus_read failed!, %s phy bus num[%d], type[%d], phyaddr = %d, nRet1 = %d, nRet2 = %d\n", ++ mii_bus->id, bus_data->phybus_num, bus_data->phybus_type, i, data1, data2); ++ } else { ++ dev_info(mii_bus->parent, ++ "read %s phy bus num[%d] type[%d] phyaddr[%d], reg2 = 0x%x, reg3 = 0x%x\n", ++ mii_bus->id, bus_data->phybus_num, bus_data->phybus_type, i, data1, data2); ++ } ++ } ++} ++ ++static inline u32 cmicd_miim_reg_read(struct cmicd_mdio_ctrl *cmic_mdio, u32 reg) ++{ ++ u32 value = readl(cmic_mdio->base + reg); ++#ifdef __BIG_ENDIAN ++ if (readl(cmic_mdio->base + CMIC_COMMON_UC0_PIO_ENDIANESS) != 0) ++ { ++ /* CMICD is in big-endian mode */ ++ value = swab32(value); ++ } ++#endif ++ return value; ++} ++ ++static inline void cmicd_miim_reg_write(struct cmicd_mdio_ctrl *cmic_mdio, u32 reg, u32 data) ++{ ++#ifdef __BIG_ENDIAN ++ if (readl(cmic_mdio->base + CMIC_COMMON_UC0_PIO_ENDIANESS) != 0) ++ { ++ /* CMICD is in big-endian mode */ ++ writel(swab32(data), cmic_mdio->base + reg); ++ return; ++ } ++#endif ++ writel(data, cmic_mdio->base + reg); ++} ++ ++static inline void cmicd_miim_set_op_read(u32 *data, u32 set) ++{ ++ SET_REG_FIELD(*data, MIIM_CTRL__MIIM_RD_START_SHIFT, ++ MIIM_CTRL__MIIM_RD_START_MASK, set); ++} ++ ++static inline void cmicd_miim_set_op_write(u32 *data, u32 set) ++{ ++ SET_REG_FIELD(*data, MIIM_CTRL__MIIM_WR_START_SHIFT, ++ MIIM_CTRL__MIIM_WR_START_MASK, set); ++} ++ ++static inline int do_cmicd_miim_op(struct cmicd_mdio_ctrl *cmic_mdio, u32 op, u32 param, u32 addr) ++{ ++ u32 val, op_done; ++ unsigned long flags; ++ int ret = 0; ++ int usec = MIIM_OP_MAX_HALT_USEC; ++ ++ if (op >= MIIM_OP_MODE_MAX) { ++ printk(KERN_ERR "%s : invalid op code %d\n", __func__, op); ++ return -EINVAL; ++ } ++ ++ /* mutex_lock(&cmic_mdio->lock); */ ++ spin_lock_irqsave(&cmic_mdio->lock, flags); ++ ++ cmicd_miim_reg_write(cmic_mdio, MIIM_PARAM_REG, param); ++ cmicd_miim_reg_write(cmic_mdio, MIIM_ADDRESS_REG, addr); ++ val = cmicd_miim_reg_read(cmic_mdio, MIIM_CTRL_REG); ++ if(op == MIIM_OP_MODE_READ) ++ cmicd_miim_set_op_read(&val, 1); ++ else ++ cmicd_miim_set_op_write(&val, 1); ++ cmicd_miim_reg_write(cmic_mdio, MIIM_CTRL_REG, val); ++ ++ do { ++ op_done = GET_REG_FIELD(cmicd_miim_reg_read(cmic_mdio, MIIM_STAT_REG), ++ MIIM_STAT__MIIM_OPN_DONE_SHIFT, MIIM_STAT__MIIM_OPN_DONE_MASK); ++ if (op_done) ++ break; ++ ++ udelay(1); ++ usec--; ++ } while (usec > 0); ++ ++ if (op_done) { ++ if(op == MIIM_OP_MODE_READ) ++ ret = cmicd_miim_reg_read(cmic_mdio, MIIM_READ_DATA_REG); ++ } ++ else ++ ret = -ETIME; ++ ++ val = cmicd_miim_reg_read(cmic_mdio, MIIM_CTRL_REG); ++ if(op == MIIM_OP_MODE_READ) ++ cmicd_miim_set_op_read(&val, 0); ++ else ++ cmicd_miim_set_op_write(&val, 0); ++ cmicd_miim_reg_write(cmic_mdio, MIIM_CTRL_REG, val); ++ ++ /* mutex_unlock(&cmic_mdio->lock); */ ++ spin_unlock_irqrestore(&cmic_mdio->lock, flags); ++ ++ return ret; ++} ++ ++ ++static int cmicd_miim_op(struct cmicd_mdio_ctrl *cmic_mdio, struct cmicd_miim_cmd *cmd) ++{ ++ u32 miim_param =0, miim_addr = 0; ++ ++ ISET_REG_FIELD(miim_param, MIIM_PARAM__BUS_ID_SHIFT, ++ MIIM_PARAM__BUS_ID_MASK, cmd->bus_id); ++ ++ if (cmd->int_sel) ++ ISET_REG_FIELD(miim_param, MIIM_PARAM__INTERNAL_SEL_SHIFT, ++ MIIM_PARAM__INTERNAL_SEL_MASK, 1); ++ ++ ISET_REG_FIELD(miim_param, MIIM_PARAM__PHY_ID_SHIFT, ++ MIIM_PARAM__PHY_ID_MASK, cmd->phy_id); ++ ++ if (cmd->op_mode == MIIM_OP_MODE_WRITE) ++ ISET_REG_FIELD(miim_param, MIIM_PARAM__PHY_DATA_SHIFT, ++ MIIM_PARAM__PHY_DATA_MASK, cmd->val); ++ ++ if (cmd->c45_sel) { ++ ISET_REG_FIELD(miim_param, MIIM_PARAM__C45_SEL_SHIFT, ++ MIIM_PARAM__C45_SEL_MASK, 1); ++ ++ ISET_REG_FIELD(miim_addr, MIIM_ADDRESS__CLAUSE_45_REGADR_SHIFT, ++ MIIM_ADDRESS__CLAUSE_45_REGADR_MASK, cmd->regnum); ++ ISET_REG_FIELD(miim_addr, MIIM_ADDRESS__CLAUSE_45_DTYPE_SHIFT, ++ MIIM_ADDRESS__CLAUSE_45_REGADR_MASK, cmd->regnum >> 16); ++ } ++ else { ++ ISET_REG_FIELD(miim_addr, MIIM_ADDRESS__CLAUSE_22_REGADR_SHIFT, ++ MIIM_ADDRESS__CLAUSE_22_REGADR_MASK, cmd->regnum); ++ } ++ ++ return do_cmicd_miim_op(cmic_mdio, cmd->op_mode, miim_param, miim_addr); ++} ++ ++ ++static int cmicd_mdiobus_read(struct mii_bus *bus, int phy_id, int regnum) ++{ ++ struct cmicd_mdiobus_private *bus_priv = bus->priv; ++ struct iproc_mdiobus_data *bus_data = &bus_priv->bus_data; ++ struct cmicd_miim_cmd cmd = {0}; ++ ++ cmd.bus_id = bus_data->phybus_num; ++ if (IPROC_MDIOBUS_TYPE_INTERNAL == bus_data->phybus_type) ++ cmd.int_sel = 1; ++ ++ cmd.phy_id = phy_id; ++ cmd.regnum = regnum; ++ ++ if (regnum & MII_ADDR_C45) ++ cmd.c45_sel = 1; ++ ++ cmd.op_mode = MIIM_OP_MODE_READ; ++ ++ return cmicd_miim_op(bus_priv->hw_ctrl, &cmd); ++} ++ ++static int cmicd_mdiobus_write(struct mii_bus *bus, int phy_id, ++ int regnum, u16 val) ++{ ++ struct cmicd_mdiobus_private *bus_priv = bus->priv; ++ struct iproc_mdiobus_data *bus_data = &bus_priv->bus_data; ++ struct cmicd_miim_cmd cmd = {0}; ++ ++ cmd.bus_id = bus_data->phybus_num; ++ if (IPROC_MDIOBUS_TYPE_INTERNAL == bus_data->phybus_type) ++ cmd.int_sel = 1; ++ ++ cmd.phy_id = phy_id; ++ cmd.regnum = regnum; ++ cmd.val = val; ++ ++ if (regnum & MII_ADDR_C45) ++ cmd.c45_sel = 1; ++ ++ cmd.op_mode = MIIM_OP_MODE_WRITE; ++ ++ return cmicd_miim_op(bus_priv->hw_ctrl, &cmd); ++} ++ ++static struct cmicd_mdio_ctrl * cmicd_mdio_res_alloc(void) ++{ ++ if (!cmic_common) { ++ cmic_common = kzalloc(sizeof(*cmic_common), GFP_KERNEL); ++ if (!cmic_common) ++ return NULL; ++ /* mutex_init(&cmic_common->lock); */ ++ spin_lock_init(&cmic_common->lock); ++ cmic_common->ref_cnt = 1; ++ } ++ else ++ cmic_common->ref_cnt ++; ++ ++ return cmic_common; ++} ++ ++static void cmicd_mdio_res_free(struct cmicd_mdio_ctrl *ctrl) ++{ ++ if (ctrl) { ++ ctrl->ref_cnt --; ++ if (ctrl->ref_cnt == 0) { ++ iounmap(ctrl->base); ++ kfree(ctrl); ++ cmic_common = NULL; ++ } ++ } ++} ++ ++static int cmicd_mdiobus_probe(struct platform_device *pdev) ++{ ++ struct mii_bus *mii_bus; ++ struct device_node *dn = pdev->dev.of_node; ++ struct cmicd_mdiobus_private *bus_priv; ++ struct iproc_mdiobus_data *bus_data; ++ struct cmicd_mdio_ctrl *cmicd_ctrl; ++ u32 mdio_bus_id; ++ u32 logical_mdio_bus_id; ++ const char *mdio_bus_type; ++ int ret; ++ ++ if (!of_device_is_available(dn)) ++ return -ENODEV; ++ ++ cmicd_ctrl = cmicd_mdio_res_alloc(); ++ if (!cmicd_ctrl) { ++ dev_err(&pdev->dev, "cmicd mdio rese alloc failed\n"); ++ ret = -ENOMEM; ++ goto err_exit; ++ } ++ ++ /* Get register base address */ ++ cmicd_ctrl->base = (void *)of_iomap(dn, 0); /*cmic_common: 0x03210000*/ ++ ++ if (of_property_read_u32(dn, "#bus-id", &mdio_bus_id)) { ++ mdio_bus_id = 2; /* no property available, use default: 2 */ ++ } ++ if (of_property_read_u32(dn, "#logical-bus-id", &logical_mdio_bus_id)) { ++ logical_mdio_bus_id = 0; /*use default:0 */ ++ } ++ if (of_property_read_string(dn, "bus-type", &mdio_bus_type)) { ++ mdio_bus_type = "external"; /* use default: "external" */ ++ } ++ ++ iproc_mdiobus_data.phybus_num = (u8) mdio_bus_id; ++ iproc_mdiobus_data.logbus_num = (u8) logical_mdio_bus_id; ++ if (!strcmp(mdio_bus_type, "internal")) ++ iproc_mdiobus_data.phybus_type = IPROC_MDIOBUS_TYPE_INTERNAL; ++ else ++ iproc_mdiobus_data.phybus_type = IPROC_MDIOBUS_TYPE_EXTERNAL; ++ iproc_mdiobus_data.logbus_type = iproc_mdiobus_data.phybus_type; ++ bus_data = &iproc_mdiobus_data; ++ ++ mii_bus = mdiobus_alloc_size(sizeof(*bus_priv)); ++ if (!mii_bus) { ++ dev_err(&pdev->dev, "mdiobus_alloc failed\n"); ++ ret = -ENOMEM; ++ goto err_ctrl_free; ++ } ++ ++ mii_bus->name = "iproc_cmicd_mdiobus"; ++ snprintf(mii_bus->id, MII_BUS_ID_SIZE, IPROC_MDIO_ID_FMT, ++ bus_data->logbus_num, bus_data->logbus_type); ++ mii_bus->parent = &pdev->dev; ++ mii_bus->read = cmicd_mdiobus_read; ++ mii_bus->write = cmicd_mdiobus_write; ++ ++ bus_priv = mii_bus->priv; ++ memcpy(&bus_priv->bus_data, bus_data, sizeof(struct iproc_mdiobus_data)); ++ bus_priv->hw_ctrl = cmicd_ctrl; ++ ++ if (IS_ENABLED(CONFIG_MACH_GH2) || IS_ENABLED(CONFIG_MACH_WH2)) ++ ret = of_mdiobus_register(mii_bus, dn); ++ else ++ ret = mdiobus_register(mii_bus); ++ if (ret) { ++ dev_err(&pdev->dev, "mdiobus_register failed\n"); ++ goto err_bus_free; ++ } ++ ++ platform_set_drvdata(pdev, mii_bus); ++ ++#if 0 ++ cmicd_mdiobus_test(mii_bus); ++#endif ++ ++ return 0; ++ ++err_bus_free: ++ kfree(mii_bus); ++err_ctrl_free: ++ cmicd_mdio_res_free(cmicd_ctrl); ++err_exit: ++ return ret; ++} ++ ++static int cmicd_mdiobus_remove(struct platform_device *pdev) ++{ ++ struct mii_bus *mii_bus = platform_get_drvdata(pdev); ++ struct cmicd_mdiobus_private *bus_priv; ++ ++ if (mii_bus) { ++ bus_priv = mii_bus->priv; ++ ++ mdiobus_unregister(mii_bus); ++ if (bus_priv) ++ cmicd_mdio_res_free(bus_priv->hw_ctrl); ++ mdiobus_free(mii_bus); ++ } ++ ++ return 0; ++} ++ ++static const struct of_device_id bcm_iproc_dt_ids[] = { ++ { .compatible = "brcm,iproc-cmicd-mdio"}, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, bcm_iproc_dt_ids); ++ ++static struct platform_driver iproc_cmicd_mdiobus_driver = ++{ ++ .driver = { ++ .name = "iproc_cmicd_mdio", ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(bcm_iproc_dt_ids), ++ }, ++ .probe = cmicd_mdiobus_probe, ++ .remove = cmicd_mdiobus_remove, ++}; ++ ++static int __init cmicd_mdio_init(void) ++{ ++ return platform_driver_register(&iproc_cmicd_mdiobus_driver); ++} ++ ++static void __exit cmicd_mdio_exit(void) ++{ ++ platform_driver_unregister(&iproc_cmicd_mdiobus_driver); ++} ++ ++//module_init(cmicd_mdio_init); ++subsys_initcall(cmicd_mdio_init); ++module_exit(cmicd_mdio_exit); ++ ++MODULE_AUTHOR("Broadcom Corporation"); ++MODULE_DESCRIPTION("iProc CMICd mdio driver"); ++MODULE_LICENSE("GPL"); ++ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/mdio/iproc_mdio.c b/drivers/net/ethernet/broadcom/mdio/iproc_mdio.c +--- a/drivers/net/ethernet/broadcom/mdio/iproc_mdio.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/mdio/iproc_mdio.c 2017-11-09 17:53:44.082291000 +0800 +@@ -0,0 +1,141 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "iproc_mdio.h" ++ ++/* Only one MDIO bus has been supported for each type */ ++static struct mii_bus *iproc_mdiobus[IPROC_MDIOBUS_TYPE_MAX] = {0}; ++ ++static struct mii_bus* ++get_iproc_mdiobus(int bustype, int phy_addr) ++{ ++ struct device *d; ++ char bus_id[MII_BUS_ID_SIZE]; ++ char phy_id[20]; ++ struct phy_device *phy_dev; ++ int idx; ++ ++ if (bustype < 0 || bustype >= IPROC_MDIOBUS_TYPE_MAX) { ++ return NULL; ++ } ++ ++ /* ++ * To support more than one bus for internal bus type on GH2, the following ++ * "if (NULL == iproc_mdiobus[bustype])" should be commented out. ++ * Note: The multi-bus support is based on the assumption that the phy_dev ++ * addresses are different for the internal bus_type bus. ++ */ ++#if !(defined(CONFIG_MACH_GH2) || (defined(CONFIG_MACH_HR3) && defined(CONFIG_MACH_WH2))) ++ if (NULL == iproc_mdiobus[bustype]) { ++#endif ++ for (idx = 0; idx < IPROC_MDIOBUS_NUM_MAX; idx++) { ++ snprintf(bus_id, MII_BUS_ID_SIZE, IPROC_MDIO_ID_FMT, idx, bustype); ++ snprintf(phy_id, 20, PHY_ID_FMT, bus_id, phy_addr); ++ d = bus_find_device_by_name(&mdio_bus_type, NULL, phy_id); ++ if (d) { ++ phy_dev = to_phy_device(d); ++ iproc_mdiobus[bustype] = phy_dev->bus; ++ idx = IPROC_MDIOBUS_NUM_MAX; ++ } ++ } ++#if !(defined(CONFIG_MACH_GH2) || (defined(CONFIG_MACH_HR3) && defined(CONFIG_MACH_WH2))) ++ } ++#endif ++ return iproc_mdiobus[bustype]; ++} ++ ++ ++/** ++ * iproc_mii_read - General iProc interface function for reading a given PHY register ++ if not registered PHY interface by phy_driver_register ++ * @busnum: currently we're using busnum value 0 ++ * @bustype: the mdio bus type, coud be IPROC_MDIOBUS_TYPE_INTERNAL or IPROC_MDIOBUS_TYPE_EXTERNAL ++ * @phy_addr: the phy address ++ * @regnum: register number to read, if MII_ADDR_C45 == (@regnum & MII_ADDR_C45), means a C45 request ++ * @val: the address to store read value if the read operation is successful ++ * ++ * Returns 0 on success, or a negative value on error. ++ */ ++int iproc_mii_read(int dev_type, int phy_addr, u32 reg_off, u16 *data) ++{ ++ struct mii_bus *mii_bus; ++ int bustype; ++ int err = -1; ++ ++ if (MII_DEV_LOCAL == dev_type) { ++ bustype = IPROC_MDIOBUS_TYPE_INTERNAL; ++ } else if (MII_DEV_EXT == dev_type) { ++ bustype = IPROC_MDIOBUS_TYPE_EXTERNAL; ++ } else { ++ return -EINVAL; ++ } ++ ++ mii_bus = get_iproc_mdiobus(bustype, phy_addr); ++ if (mii_bus) { ++ err = mii_bus->read(mii_bus, phy_addr, reg_off); ++ if (err >= 0) { ++ *data = err; ++ } ++ } else { ++ pr_err("%s : mdiobus:%d:%d is invalid!\n", __func__, 0, bustype); ++ } ++ ++ return err; ++} ++EXPORT_SYMBOL(iproc_mii_read); ++ ++/** ++ * iproc_mii_write - General iProc interface function for writing a given PHY register ++ if not registered PHY interface by phy_driver_register ++ * @busnum: currently we're using busnum value 0 ++ * @bustype: the mdio bus type, coud be IPROC_MDIOBUS_TYPE_INTERNAL or IPROC_MDIOBUS_TYPE_EXTERNAL ++ * @phy_addr: the phy address ++ * @regnum: register number to write, if MII_ADDR_C45 == (@regnum & MII_ADDR_C45), means a C45 request ++ * @val: value to write to @regnum ++ * ++ * Returns 0 on success, or a negative value on error. ++ */ ++int iproc_mii_write(int dev_type, int phy_addr, u32 reg_off, u16 data) ++{ ++ struct mii_bus *mii_bus; ++ int bustype; ++ int err = -1; ++ ++ if (MII_DEV_LOCAL == dev_type) { ++ bustype = IPROC_MDIOBUS_TYPE_INTERNAL; ++ } else if (MII_DEV_EXT == dev_type) { ++ bustype = IPROC_MDIOBUS_TYPE_EXTERNAL; ++ } else { ++ return -EINVAL; ++ } ++ ++ mii_bus = get_iproc_mdiobus(bustype, phy_addr); ++ if (mii_bus) { ++ err = mii_bus->write(mii_bus, phy_addr, reg_off, data); ++ } else { ++ pr_err("%s : mdiobus:%d:%d is invalid!\n", __func__, 0, bustype); ++ } ++ ++ return err; ++} ++EXPORT_SYMBOL(iproc_mii_write); ++ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/mdio/iproc_mdio.h b/drivers/net/ethernet/broadcom/mdio/iproc_mdio.h +--- a/drivers/net/ethernet/broadcom/mdio/iproc_mdio.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/mdio/iproc_mdio.h 2017-11-09 17:53:44.082312000 +0800 +@@ -0,0 +1,97 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ */ ++ ++ ++#ifndef _bcm5301x_ccb_mii_h_ ++#define _bcm5301x_ccb_mii_h_ ++ ++#include ++ ++typedef struct _mdio_info_s { ++ void *h; /* dev handle */ ++ spinlock_t lock; ++} mdio_info_t; ++ ++/* reutrn value for MII driver */ ++#define MII_ERR_NONE 0 ++#define MII_ERR_TIMEOUT -1 ++#define MII_ERR_INTERNAL -2 ++#define MII_ERR_PARAM -3 ++#define MII_ERR_UNAVAIL -4 ++#define MII_ERR_UNKNOW -5 ++#define MII_ERR_INIT -6 ++ ++/* device type */ ++#define MII_DEV_LOCAL 0 ++#define MII_DEV_EXT 1 ++ ++/* MII register definition */ ++#define MII_MGMT 0x18003000 ++#define MII_MGMT_BASE 0x000 ++#define MII_MGMT_DATAMASK 0x000007ff ++#define MII_CMD_DATA 0x18003004 ++#define MII_CMD_DATA_BASE 0x004 ++#define MII_CMD_DATA_DATAMASK 0xffffffff ++ ++/* fields in MII_MGMT */ ++#define MII_MGMT_BYP_MASK 0x00000400 ++#define MII_MGMT_BYP_SHIFT 10 ++#define MII_MGMT_EXP_MASK 0x00000200 ++#define MII_MGMT_EXP_SHIFT 9 ++#define MII_MGMT_BSY_MASK 0x00000100 ++#define MII_MGMT_BSY_SHIFT 8 ++#define MII_MGMT_PRE_MASK 0x00000080 ++#define MII_MGMT_PRE_SHIFT 7 ++#define MII_MGMT_MDCDIV_MASK 0x0000007f ++#define MII_MGMT_MDCDIV_SHIFT 0 ++/* fields in MII_CMD_DATA */ ++#define MII_CMD_DATA_SB_MASK 0xc0000000 ++#define MII_CMD_DATA_SB_SHIFT 30 ++#define MII_CMD_DATA_OP_MASK 0x30000000 ++#define MII_CMD_DATA_OP_SHIFT 28 ++#define MII_CMD_DATA_PA_MASK 0x0f800000 ++#define MII_CMD_DATA_PA_SHIFT 23 ++#define MII_CMD_DATA_RA_MASK 0x007c0000 ++#define MII_CMD_DATA_RA_SHIFT 18 ++#define MII_CMD_DATA_TA_MASK 0x00030000 ++#define MII_CMD_DATA_TA_SHIFT 16 ++#define MII_CMD_DATA_DATA_MASK 0x0000ffff ++#define MII_CMD_DATA_DATA_SHIFT 0 ++ ++ ++/****** iProc General Interface for mdio bus support ******/ ++struct iproc_mdiobus_data { ++ /* the mdio bus num and type from chip view */ ++ u8 logbus_num; ++ u8 logbus_type; ++ /* the actual bus num and type that mdio bus comes from */ ++ u8 phybus_num; ++ u8 phybus_type; ++ /* Note : ++ * Usually the logbus_num and logbus_type are the same as phybus_num and ++ * phybus_type, but they may be different on some special cases. For example, ++ * we may use cmicd mdio external bus 2 for the iProc mdio external bus 0, ++ * this configuration could be described as phybus_num=2, phybus_type=external, ++ * logbus_num=0, logbus_type=external. From iProc's view, the Phy devices ++ * for iProc AMAC should use mdiobus by logbus_num and logbus_type. But internally ++ * we'll configure the mdio core by phybus_num and phybus_type. ++ */ ++}; ++ ++#define IPROC_MDIOBUS_TYPE_INTERNAL 0 ++#define IPROC_MDIOBUS_TYPE_EXTERNAL 1 ++ ++#define IPROC_MDIOBUS_NUM_MAX 8 ++#define IPROC_MDIOBUS_TYPE_MAX 2 ++ ++/* iproc_mii:[bus_num]:[bus_type] */ ++#define IPROC_MDIO_ID_FMT "iproc_mii:%01x:%01x" ++ ++ ++/* General interface for iProc mdio bus read/write function */ ++extern int iproc_mii_read(int dev_type, int phy_addr, u32 reg_off, u16 *data); ++extern int iproc_mii_write(int dev_type, int phy_addr, u32 reg_off, u16 data); ++/****** iProc General Interface for mdio bus support ******/ ++ ++#endif /* _bcm5301x_ccb_mii_h_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/mdio/iproc_mdio_dev.h b/drivers/net/ethernet/broadcom/mdio/iproc_mdio_dev.h +--- a/drivers/net/ethernet/broadcom/mdio/iproc_mdio_dev.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/mdio/iproc_mdio_dev.h 2017-11-09 17:53:44.083307000 +0800 +@@ -0,0 +1,32 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ */ ++ ++ ++#ifndef _IPROC_MDIO_DEV_H ++#define _IPROC_MDIO_DEV_H ++ ++/* IOCTL commands */ ++ ++#define MDIO_IOC_MAGIC 'm' ++ ++struct mdio_ioc_transfer { ++ uint8_t pa; /* phy address */ ++ uint8_t ra; /* register address */ ++ uint16_t tx_buf; ++ uint16_t rx_buf; ++}; ++ ++#define MDIO_MSGSIZE(N) \ ++ ((((N)*(sizeof (struct mdio_ioc_transfer))) < (1 << _IOC_SIZEBITS)) \ ++ ? ((N)*(sizeof (struct mdio_ioc_transfer))) : 0) ++ ++#define MDIO_IOC_MESSAGE(N) _IOW(MDIO_IOC_MAGIC, 0, char[MDIO_MSGSIZE(N)]) ++ ++#define MDIO_IOC_EXTERNAL_R_REG _IOWR(MDIO_IOC_MAGIC, 0, char[MDIO_MSGSIZE(1)]) ++#define MDIO_IOC_EXTERNAL_W_REG _IOW(MDIO_IOC_MAGIC, 1, char[MDIO_MSGSIZE(1)]) ++#define MDIO_IOC_LOCAL_R_REG _IOWR(MDIO_IOC_MAGIC, 2, char[MDIO_MSGSIZE(1)]) ++#define MDIO_IOC_LOCAL_W_REG _IOW(MDIO_IOC_MAGIC, 3, char[MDIO_MSGSIZE(1)]) ++ ++ ++#endif +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig +--- a/drivers/pci/host/Kconfig 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/pci/host/Kconfig 2017-11-09 17:53:50.841348000 +0800 +@@ -118,6 +118,15 @@ config PCI_VERSATILE + bool "ARM Versatile PB PCI controller" + depends on ARCH_VERSATILE + ++config PCIE_XGS_IPROC ++ tristate "Broadcom XGS iProc PCIe controller" ++ select PCI_DOMAINS ++ depends on ARCH_XGS_IPROC ++ default n ++ help ++ This enables the XGS iProc PCIe core controller support for Broadcom's ++ iProc family of SoCs. ++ + config PCIE_IPROC + tristate "Broadcom iProc PCIe controller" + depends on OF && (ARM || ARM64) +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile +--- a/drivers/pci/host/Makefile 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/pci/host/Makefile 2017-11-09 17:53:50.842362000 +0800 +@@ -16,6 +16,7 @@ obj-$(CONFIG_PCI_LAYERSCAPE) += pci-laye + obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o + obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o + obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o ++obj-$(CONFIG_PCIE_XGS_IPROC) += pcie-xgs-iproc.o + obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o + obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o + obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/pci/host/pcie-xgs-iproc.c b/drivers/pci/host/pcie-xgs-iproc.c +--- a/drivers/pci/host/pcie-xgs-iproc.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/pci/host/pcie-xgs-iproc.c 2017-11-09 17:53:50.893339000 +0800 +@@ -0,0 +1,469 @@ ++/* ++ * Copyright (C) 2014 Hauke Mehrtens ++ * Copyright (C) 2015 Broadcom Corporation ++ * ++ * 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 version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define CLK_CONTROL_OFFSET 0x000 ++ ++#define CFG_IND_ADDR_OFFSET 0x120 ++#define CFG_IND_ADDR_MASK 0x00001ffc ++#define CFG_IND_DATA_OFFSET 0x124 ++ ++#define CFG_ADDR_OFFSET 0x1f8 ++#define CFG_ADDR_BUS_NUM_SHIFT 20 ++#define CFG_ADDR_BUS_NUM_MASK 0x0ff00000 ++#define CFG_ADDR_DEV_NUM_SHIFT 15 ++#define CFG_ADDR_DEV_NUM_MASK 0x000f8000 ++#define CFG_ADDR_FUNC_NUM_SHIFT 12 ++#define CFG_ADDR_FUNC_NUM_MASK 0x00007000 ++#define CFG_ADDR_REG_NUM_SHIFT 2 ++#define CFG_ADDR_REG_NUM_MASK 0x00000ffc ++#define CFG_ADDR_CFG_TYPE_SHIFT 0 ++#define CFG_ADDR_CFG_TYPE_MASK 0x00000003 ++ ++#define CFG_DATA_OFFSET 0x1fc ++ ++#define SYS_RC_INTX_EN 0x330 ++#define SYS_RC_INTX_MASK 0xf ++ ++#define IPROC_PCIE_MAX_NUM_IRQS 6 ++ ++/** ++ * iProc PCIe device ++ * @dev: pointer to device data structure ++ * @base: PCIe host controller I/O register base ++ * @resources: linked list of all PCI resources ++ * @sysdata: Per PCI controller data (ARM-specific) ++ * @root_bus: pointer to root bus ++ * @phy: optional PHY device that controls the Serdes ++ * @irqs: interrupt IDs ++ */ ++struct iproc_pcie { ++ struct device *dev; ++ void __iomem *base; ++#ifdef CONFIG_ARM ++ struct pci_sys_data sysdata; ++#endif ++ struct pci_bus *root_bus; ++ struct phy *phy; ++ int irqs[IPROC_PCIE_MAX_NUM_IRQS]; ++ int (*map_irq)(const struct pci_dev *, u8, u8); ++}; ++ ++#if (defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_HR3) \ ++ || defined(CONFIG_MACH_GH2)) ++#define PCI_PERST_SWR (1) ++#define PCI_CONFIG_SWR (1) ++#else ++#define PCI_PERST_SWR (0) ++#define PCI_CONFIG_SWR (0) ++#endif /* defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_HR3) || defined(CONFIG_MACH_GH2)*/ ++ ++#if PCI_CONFIG_SWR ++extern char * nvram_get(const char *name); ++#endif /* PCI_CONFIG_SWR */ ++ ++#define MII_DEV_LOCAL 0 ++extern int iproc_mii_write(int dev_type, int phy_addr, u32 reg_off, u16 data); ++ ++static inline struct iproc_pcie *iproc_pcie_data(struct pci_bus *bus) ++{ ++ struct iproc_pcie *pcie; ++#ifdef CONFIG_ARM ++ struct pci_sys_data *sys = bus->sysdata; ++ ++ pcie = sys->private_data; ++#else ++ pcie = bus->sysdata; ++#endif ++ return pcie; ++} ++ ++/** ++ * Note access to the configuration registers are protected at the higher layer ++ * by 'pci_lock' in drivers/pci/access.c ++ */ ++static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus, ++ unsigned int devfn, ++ int where) ++{ ++ struct iproc_pcie *pcie = iproc_pcie_data(bus); ++ unsigned slot = PCI_SLOT(devfn); ++ unsigned fn = PCI_FUNC(devfn); ++ unsigned busno = bus->number; ++ u32 val; ++ ++ /* root complex access */ ++ if (busno == 0) { ++ if (slot >= 1) ++ return NULL; ++ writel(where & CFG_IND_ADDR_MASK, ++ pcie->base + CFG_IND_ADDR_OFFSET); ++ return (pcie->base + CFG_IND_DATA_OFFSET); ++ } ++ ++ if (fn > 1) ++ return NULL; ++ ++ /* EP device access */ ++ val = (busno << CFG_ADDR_BUS_NUM_SHIFT) | ++ (slot << CFG_ADDR_DEV_NUM_SHIFT) | ++ (fn << CFG_ADDR_FUNC_NUM_SHIFT) | ++ (where & CFG_ADDR_REG_NUM_MASK) | ++ (1 & CFG_ADDR_CFG_TYPE_MASK); ++ writel(val, pcie->base + CFG_ADDR_OFFSET); ++ ++ return (pcie->base + CFG_DATA_OFFSET); ++} ++ ++static struct pci_ops iproc_pcie_ops = { ++ .map_bus = iproc_pcie_map_cfg_bus, ++ .read = pci_generic_config_read32, ++ .write = pci_generic_config_write32, ++}; ++ ++static void iproc_pcie_reset(struct iproc_pcie *pcie) ++{ ++ /* Configure the PCIe controller as root complex and send a downstream reset */ ++ writel(0, pcie->base + CLK_CONTROL_OFFSET); ++ mdelay(1); ++ writel(1, pcie->base + CLK_CONTROL_OFFSET); ++ mdelay(100); ++} ++ ++#if (defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_SB2) || defined(CONFIG_MACH_HR3) || defined(CONFIG_MACH_GH2)) ++static int pcie_serdes_reg_write(int phyaddr, int reg, u16 val) ++{ ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x1f, reg & 0xfff0); ++ iproc_mii_write(MII_DEV_LOCAL, phyaddr, reg & 0xf, val); ++ ++ return PCIBIOS_SUCCESSFUL; ++} ++ ++static int pcie_rc_war(struct iproc_pcie * pcie) ++{ ++ /* Setting for PCIe Serdes PLL output */ ++ pcie_serdes_reg_write(2, 0x2103, 0x2b1c); ++ pcie_serdes_reg_write(2, 0x1300, 0x000b); ++ mdelay(100); ++ ++#if PCI_PERST_SWR ++ iproc_pcie_reset(pcie); ++#endif /* PCI_PERST_SWR */ ++ ++ return PCIBIOS_SUCCESSFUL; ++} ++#endif /* CONFIG_MACH_GH || CONFIG_MACH_SB2) || CONFIG_MACH_HR3 || defined(CONFIG_MACH_GH2) */ ++ ++static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus) ++{ ++ u8 hdr_type; ++ u32 link_ctrl; ++ u16 pos, link_status; ++ bool link_is_active = false; ++ u32 class; ++#if PCI_CONFIG_SWR ++ u32 tmp32, devfn = 0; ++ char *pcie_configs = NULL; ++#endif /* PCI_CONFIG_SWR */ ++ ++ ++ /* make sure we are not in EP mode */ ++ pci_bus_read_config_byte(bus, 0, PCI_HEADER_TYPE, &hdr_type); ++ if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE) { ++ dev_err(pcie->dev, "in EP mode, hdr=%#02x\n", hdr_type); ++ return -EFAULT; ++ } ++ ++#if (defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_SB2) || defined(CONFIG_MACH_HR3) || defined(CONFIG_MACH_GH2)) ++ pcie_rc_war(pcie); ++#endif ++ ++#if PCI_CONFIG_SWR ++ pcie_configs = nvram_get("pcie_configs"); ++ if (pcie_configs) { ++ if (!strcmp(pcie_configs, "tx-de-emp")) { ++ pci_bus_read_config_dword(bus, devfn, 0xdc, &tmp32); ++ tmp32 |= (0x1 << 6); ++ pci_bus_write_config_dword(bus, devfn, 0xdc, tmp32); ++ pci_bus_read_config_dword(bus, devfn, 0xdc, &tmp32); ++ } ++ } ++#endif /* PCI_CONFIG_SWR */ ++ ++ /* force class to PCI_CLASS_BRIDGE_PCI (0x0604) */ ++ /* ++ * After this modification, the CLASS code in configuration space would be ++ * read as PCI_CLASS_BRIDGE_PCI(0x0604) instead of network interface(0x0200) ++ */ ++#define PCI_BRIDGE_CTRL_REG_OFFSET 0x43c ++#define PCI_CLASS_BRIDGE_MASK 0xffff00 ++#define PCI_CLASS_BRIDGE_SHIFT 8 ++ pci_bus_read_config_dword(bus, 0, PCI_BRIDGE_CTRL_REG_OFFSET, &class); ++ class &= ~PCI_CLASS_BRIDGE_MASK; ++ class |= (PCI_CLASS_BRIDGE_PCI << PCI_CLASS_BRIDGE_SHIFT); ++ pci_bus_write_config_dword(bus, 0, PCI_BRIDGE_CTRL_REG_OFFSET, class); ++ ++ /* check link status to see if link is active */ ++ pos = pci_bus_find_capability(bus, 0, PCI_CAP_ID_EXP); ++ pci_bus_read_config_word(bus, 0, pos + PCI_EXP_LNKSTA, &link_status); ++ if (link_status & PCI_EXP_LNKSTA_NLW) ++ link_is_active = true; ++ ++ if (!link_is_active) { ++ /* try GEN 1 link speed */ ++#define PCI_LINK_STATUS_CTRL_2_OFFSET 0x0dc ++#define PCI_TARGET_LINK_SPEED_MASK 0xf ++#define PCI_TARGET_LINK_SPEED_GEN2 0x2 ++#define PCI_TARGET_LINK_SPEED_GEN1 0x1 ++ pci_bus_read_config_dword(bus, 0, ++ PCI_LINK_STATUS_CTRL_2_OFFSET, ++ &link_ctrl); ++ if ((link_ctrl & PCI_TARGET_LINK_SPEED_MASK) == ++ PCI_TARGET_LINK_SPEED_GEN2) { ++ link_ctrl &= ~PCI_TARGET_LINK_SPEED_MASK; ++ link_ctrl |= PCI_TARGET_LINK_SPEED_GEN1; ++ pci_bus_write_config_dword(bus, 0, ++ PCI_LINK_STATUS_CTRL_2_OFFSET, ++ link_ctrl); ++ msleep(100); ++ ++ pos = pci_bus_find_capability(bus, 0, PCI_CAP_ID_EXP); ++ pci_bus_read_config_word(bus, 0, pos + PCI_EXP_LNKSTA, ++ &link_status); ++ if (link_status & PCI_EXP_LNKSTA_NLW) ++ link_is_active = true; ++ } ++ } ++ ++ dev_info(pcie->dev, "link: %s\n", link_is_active ? "UP" : "DOWN"); ++ ++ return link_is_active ? 0 : -ENODEV; ++} ++ ++static void iproc_pcie_enable(struct iproc_pcie *pcie) ++{ ++ writel(SYS_RC_INTX_MASK, pcie->base + SYS_RC_INTX_EN); ++} ++ ++int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res) ++{ ++ int ret; ++ void *sysdata; ++ struct pci_bus *bus; ++ ++ if (!pcie || !pcie->dev || !pcie->base) ++ return -EINVAL; ++ ++ ret = phy_init(pcie->phy); ++ if (ret) { ++ dev_err(pcie->dev, "unable to initialize PCIe PHY\n"); ++ return ret; ++ } ++ ++ ret = phy_power_on(pcie->phy); ++ if (ret) { ++ dev_err(pcie->dev, "unable to power on PCIe PHY\n"); ++ goto err_exit_phy; ++ } ++ ++ iproc_pcie_reset(pcie); ++ ++#ifdef CONFIG_ARM ++ pcie->sysdata.private_data = pcie; ++ sysdata = &pcie->sysdata; ++#else ++ sysdata = pcie; ++#endif ++ ++ bus = pci_create_root_bus(pcie->dev, 0, &iproc_pcie_ops, sysdata, res); ++ if (!bus) { ++ dev_err(pcie->dev, "unable to create PCI root bus\n"); ++ ret = -ENOMEM; ++ goto err_power_off_phy; ++ } ++ pcie->root_bus = bus; ++ ++ ret = iproc_pcie_check_link(pcie, bus); ++ if (ret) { ++ dev_err(pcie->dev, "no PCIe EP device detected\n"); ++ goto err_rm_root_bus; ++ } ++ ++ iproc_pcie_enable(pcie); ++ ++ pci_scan_child_bus(bus); ++ pci_assign_unassigned_bus_resources(bus); ++#ifdef CONFIG_ARM ++ pci_fixup_irqs(pci_common_swizzle, pcie->map_irq); ++#endif ++ pci_bus_add_devices(bus); ++ ++ return 0; ++ ++err_rm_root_bus: ++ pci_stop_root_bus(bus); ++ pci_remove_root_bus(bus); ++ ++err_power_off_phy: ++ phy_power_off(pcie->phy); ++err_exit_phy: ++ phy_exit(pcie->phy); ++ return ret; ++} ++EXPORT_SYMBOL(iproc_pcie_setup); ++ ++ ++#if ( defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || defined(CONFIG_MACH_HR2) ) ++static void WrongPCIGen2TemplateWAR(int port, u32 reg, u16 val) ++{ ++ /* port = phy addr */ ++ iproc_mii_write(MII_DEV_LOCAL, port, 0x1f, 0x8630); ++ iproc_mii_write(MII_DEV_LOCAL, port, reg, val); ++} ++#endif /* defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_SKT2) || defined(CONFIG_MACH_HR2) */ ++ ++ ++int iproc_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin) ++{ ++ struct iproc_pcie *pcie = iproc_pcie_data(pdev->bus); ++ int irq = pcie->irqs[4]; ++ ++ return irq; ++} ++ ++static int iproc_pcie_probe(struct platform_device *pdev) ++{ ++ struct iproc_pcie *pcie; ++ struct device_node *np = pdev->dev.of_node; ++ struct resource reg; ++ resource_size_t iobase = 0; ++ LIST_HEAD(res); ++ int ret; ++ //u32 irqs_total; ++ int i; ++ ++ pcie = devm_kzalloc(&pdev->dev, sizeof(struct iproc_pcie), GFP_KERNEL); ++ if (!pcie) ++ return -ENOMEM; ++ ++ pcie->dev = &pdev->dev; ++ platform_set_drvdata(pdev, pcie); ++ ++ ret = of_address_to_resource(np, 0, ®); ++ if (ret < 0) { ++ dev_err(pcie->dev, "unable to obtain controller resources\n"); ++ return ret; ++ } ++ ++ pcie->base = devm_ioremap_resource(pcie->dev, ®); ++ if (IS_ERR(pcie->base)) ++ return PTR_ERR(pcie->base); ++ ++ /* PHY use is optional */ ++ pcie->phy = devm_phy_get(&pdev->dev, "pcie-phy"); ++ if (IS_ERR(pcie->phy)) { ++ if (PTR_ERR(pcie->phy) == -EPROBE_DEFER) ++ return -EPROBE_DEFER; ++ pcie->phy = NULL; ++ } ++ ++ ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &iobase); ++ if (ret) { ++ dev_err(pcie->dev, ++ "unable to get PCI host bridge resources\n"); ++ return ret; ++ } ++ ++#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || defined(CONFIG_MACH_HR2)) ++// if (of_device_is_compatible(np, "iproc-p2") || of_device_is_compatible(np, "iproc-p6")) { ++ WrongPCIGen2TemplateWAR(of_get_pci_domain_nr(np) + 7, 0x13, 0x190); ++ WrongPCIGen2TemplateWAR(of_get_pci_domain_nr(np) + 7, 0x19, 0x191); ++// } ++#endif ++ ++ /*Parse IRQ*/ ++ /* of_irq_count is not exported for module to call */ ++#if 0 ++ irqs_total = of_irq_count(np); ++ if ( !irqs_total || (irqs_total > IPROC_PCIE_MAX_NUM_IRQS) ) ++ return -EINVAL; ++#endif ++ ++ for (i = 0; i < IPROC_PCIE_MAX_NUM_IRQS; i++) { ++ pcie->irqs[i] = irq_of_parse_and_map(np, i); ++ if (!pcie->irqs[i]) { ++ dev_err(&pdev->dev, "unable to parse or map irq index:%d\n", i); ++ return -EINVAL; ++ } ++ } ++ ++ //pcie->map_irq = of_irq_parse_and_map_pci; ++ pcie->map_irq = iproc_pcie_map_irq; ++ ++ ret = iproc_pcie_setup(pcie, &res); ++ if (ret) ++ dev_err(pcie->dev, "PCIe controller setup failed\n"); ++ ++ pci_free_resource_list(&res); ++ ++ return ret; ++} ++ ++static int iproc_pcie_remove(struct platform_device *pdev) ++{ ++ struct iproc_pcie *pcie = platform_get_drvdata(pdev); ++ ++ pci_stop_root_bus(pcie->root_bus); ++ pci_remove_root_bus(pcie->root_bus); ++ ++ phy_power_off(pcie->phy); ++ phy_exit(pcie->phy); ++ ++ return 0; ++} ++ ++static const struct of_device_id iproc_pcie_of_match_table[] = { ++ { .compatible = "brcm,iproc-pcie", }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, iproc_pcie_of_match_table); ++ ++static struct platform_driver iproc_pcie_pltfm_driver = { ++ .driver = { ++ .name = "iproc-pcie", ++ .of_match_table = of_match_ptr(iproc_pcie_of_match_table), ++ }, ++ .probe = iproc_pcie_probe, ++ .remove = iproc_pcie_remove, ++}; ++ ++module_platform_driver(iproc_pcie_pltfm_driver); ++ ++MODULE_DESCRIPTION("Broadcom XGS iProc PCIe driver"); ++MODULE_LICENSE("GPL v2"); +\ No newline at end of file +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/soc/Kconfig b/drivers/soc/Kconfig +--- a/drivers/soc/Kconfig 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/soc/Kconfig 2017-11-09 17:53:55.652386000 +0800 +@@ -1,6 +1,7 @@ + menu "SOC (System On Chip) specific Drivers" + + source "drivers/soc/brcmstb/Kconfig" ++source "drivers/soc/bcm/Kconfig" + source "drivers/soc/mediatek/Kconfig" + source "drivers/soc/qcom/Kconfig" + source "drivers/soc/rockchip/Kconfig" +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/soc/Makefile b/drivers/soc/Makefile +--- a/drivers/soc/Makefile 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/soc/Makefile 2017-11-09 17:53:55.653381000 +0800 +@@ -2,6 +2,7 @@ + # Makefile for the Linux Kernel SOC specific device drivers. + # + ++obj-$(CONFIG_SOC_XGS_IPROC) += bcm/ + obj-$(CONFIG_SOC_BRCMSTB) += brcmstb/ + obj-$(CONFIG_MACH_DOVE) += dove/ + obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/soc/bcm/Kconfig b/drivers/soc/bcm/Kconfig +--- a/drivers/soc/bcm/Kconfig 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/soc/bcm/Kconfig 2017-11-09 17:53:55.664395000 +0800 +@@ -0,0 +1,8 @@ ++menuconfig SOC_XGS_IPROC ++ bool "Broadcom XGS iProc IDM/DMU/PMU drivers" ++ depends on ARCH_XGS_IPROC ++ default ARCH_XGS_IPROC ++ help ++ This option enables XGS iProc IDM/DMU/PMU related drivers. ++ ++ If unsure, say Y. +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/soc/bcm/Makefile b/drivers/soc/bcm/Makefile +--- a/drivers/soc/bcm/Makefile 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/soc/bcm/Makefile 2017-11-09 17:53:55.665375000 +0800 +@@ -0,0 +1 @@ ++obj-$(CONFIG_SOC_XGS_IPROC) += xgs-iproc-wrap-idm-dmu.o xgs-iproc-idm.o +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/soc/bcm/xgs-iproc-idm.c b/drivers/soc/bcm/xgs-iproc-idm.c +--- a/drivers/soc/bcm/xgs-iproc-idm.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/soc/bcm/xgs-iproc-idm.c 2017-11-09 17:53:55.666387000 +0800 +@@ -0,0 +1,842 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++extern void __iomem *get_iproc_idm_base(int); ++extern void __iomem *get_iproc_idm_base_phys(int); ++ ++#if defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || \ ++ defined(CONFIG_MACH_HR2) ++#define IHOST_S1_IDM_ERROR_LOG_CONTROL 0x18107900 ++#define IHOST_S1_IDM_ERROR_LOG_COMPLETE 0x18107904 ++#define IHOST_S1_IDM_ERROR_LOG_STATUS 0x18107908 ++#define IHOST_S1_IDM_ERROR_LOG_ADDR_LSB 0x1810790c ++#define IHOST_S1_IDM_ERROR_LOG_ID 0x18107914 ++#define IHOST_S1_IDM_ERROR_LOG_FLAGS 0x1810791c ++#define IHOST_S1_IDM_INTERRUPT_STATUS 0x18107a00 ++#define IHOST_S0_IDM_ERROR_LOG_CONTROL 0x18108900 ++#define IHOST_S0_IDM_ERROR_LOG_COMPLETE 0x18108904 ++#define IHOST_S0_IDM_ERROR_LOG_STATUS 0x18108908 ++#define IHOST_S0_IDM_ERROR_LOG_ADDR_LSB 0x1810890c ++#define IHOST_S0_IDM_ERROR_LOG_ID 0x18108914 ++#define IHOST_S0_IDM_ERROR_LOG_FLAGS 0x1810891c ++#define IHOST_S0_IDM_INTERRUPT_STATUS 0x18108a00 ++#define DDR_S1_IDM_ERROR_LOG_CONTROL 0x18109900 ++#define DDR_S1_IDM_ERROR_LOG_COMPLETE 0x18109904 ++#define DDR_S1_IDM_ERROR_LOG_STATUS 0x18109908 ++#define DDR_S1_IDM_ERROR_LOG_ADDR_LSB 0x1810990c ++#define DDR_S1_IDM_ERROR_LOG_ID 0x18109914 ++#define DDR_S1_IDM_ERROR_LOG_FLAGS 0x1810991c ++#define DDR_S1_IDM_INTERRUPT_STATUS 0x18109a00 ++#define DDR_S2_IDM_ERROR_LOG_CONTROL 0x1810a900 ++#define DDR_S2_IDM_ERROR_LOG_COMPLETE 0x1810a904 ++#define DDR_S2_IDM_ERROR_LOG_STATUS 0x1810a908 ++#define DDR_S2_IDM_ERROR_LOG_ADDR_LSB 0x1810a90c ++#define DDR_S2_IDM_ERROR_LOG_ID 0x1810a914 ++#define DDR_S2_IDM_ERROR_LOG_FLAGS 0x1810a91c ++#define DDR_S2_IDM_INTERRUPT_STATUS 0x1810aa00 ++#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_CONTROL 0x1810b900 ++#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_COMPLETE 0x1810b904 ++#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_STATUS 0x1810b908 ++#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1810b90c ++#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_ID 0x1810b914 ++#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_FLAGS 0x1810b91c ++#define AXI_PCIE_S0_IDM_IDM_INTERRUPT_STATUS 0x1810ba00 ++#define CMICD_S0_IDM_IDM_ERROR_LOG_CONTROL 0x1810d900 ++#define CMICD_S0_IDM_IDM_ERROR_LOG_COMPLETE 0x1810d904 ++#define CMICD_S0_IDM_IDM_ERROR_LOG_STATUS 0x1810d908 ++#define CMICD_S0_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1810d90c ++#define CMICD_S0_IDM_IDM_ERROR_LOG_ID 0x1810d914 ++#define CMICD_S0_IDM_IDM_ERROR_LOG_FLAGS 0x1810d91c ++#define CMICD_S0_IDM_IDM_INTERRUPT_STATUS 0x1810da00 ++#define APBY_S0_IDM_IDM_ERROR_LOG_CONTROL 0x1810f900 ++#define APBY_S0_IDM_IDM_ERROR_LOG_COMPLETE 0x1810f904 ++#define APBY_S0_IDM_IDM_ERROR_LOG_STATUS 0x1810f908 ++#define APBY_S0_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1810f90c ++#define APBY_S0_IDM_IDM_ERROR_LOG_ID 0x1810f914 ++#define APBY_S0_IDM_IDM_ERROR_LOG_FLAGS 0x1810f91c ++#define APBY_S0_IDM_IDM_INTERRUPT_STATUS 0x1810fa00 ++#define ROM_S0_IDM_ERROR_LOG_CONTROL 0x1811a900 ++#define ROM_S0_IDM_ERROR_LOG_COMPLETE 0x1811a904 ++#define ROM_S0_IDM_ERROR_LOG_STATUS 0x1811a908 ++#define ROM_S0_IDM_ERROR_LOG_ADDR_LSB 0x1811a90c ++#define ROM_S0_IDM_ERROR_LOG_ID 0x1811a914 ++#define ROM_S0_IDM_ERROR_LOG_FLAGS 0x1811a91c ++#define ROM_S0_IDM_INTERRUPT_STATUS 0x1811aa00 ++#define NAND_IDM_IDM_ERROR_LOG_CONTROL 0x1811b900 ++#define NAND_IDM_IDM_ERROR_LOG_COMPLETE 0x1811b904 ++#define NAND_IDM_IDM_ERROR_LOG_STATUS 0x1811b908 ++#define NAND_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1811b90c ++#define NAND_IDM_IDM_ERROR_LOG_ID 0x1811b914 ++#define NAND_IDM_IDM_ERROR_LOG_FLAGS 0x1811b91c ++#define NAND_IDM_IDM_INTERRUPT_STATUS 0x1811ba00 ++#define QSPI_IDM_IDM_ERROR_LOG_CONTROL 0x1811c900 ++#define QSPI_IDM_IDM_ERROR_LOG_COMPLETE 0x1811c904 ++#define QSPI_IDM_IDM_ERROR_LOG_STATUS 0x1811c908 ++#define QSPI_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1811c90c ++#define QSPI_IDM_IDM_ERROR_LOG_ID 0x1811c914 ++#define QSPI_IDM_IDM_ERROR_LOG_FLAGS 0x1811c91c ++#define QSPI_IDM_IDM_INTERRUPT_STATUS 0x1811ca00 ++#define A9JTAG_S0_IDM_IDM_ERROR_LOG_CONTROL 0x1811d900 ++#define A9JTAG_S0_IDM_IDM_ERROR_LOG_COMPLETE 0x1811d904 ++#define A9JTAG_S0_IDM_IDM_ERROR_LOG_STATUS 0x1811d908 ++#define A9JTAG_S0_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1811d90c ++#define A9JTAG_S0_IDM_IDM_ERROR_LOG_ID 0x1811d914 ++#define A9JTAG_S0_IDM_IDM_ERROR_LOG_FLAGS 0x1811d91c ++#define A9JTAG_S0_IDM_IDM_INTERRUPT_STATUS 0x1811da00 ++#define SRAM_S0_IDM_ERROR_LOG_CONTROL 0x18120900 ++#define SRAM_S0_IDM_ERROR_LOG_COMPLETE 0x18120904 ++#define SRAM_S0_IDM_ERROR_LOG_STATUS 0x18120908 ++#define SRAM_S0_IDM_ERROR_LOG_ADDR_LSB 0x1812090c ++#define SRAM_S0_IDM_ERROR_LOG_ID 0x18120914 ++#define SRAM_S0_IDM_ERROR_LOG_FLAGS 0x1812091c ++#define SRAM_S0_IDM_INTERRUPT_STATUS 0x18120a00 ++#define APBZ_S0_IDM_IDM_ERROR_LOG_CONTROL 0x18121900 ++#define APBZ_S0_IDM_IDM_ERROR_LOG_COMPLETE 0x18121904 ++#define APBZ_S0_IDM_IDM_ERROR_LOG_STATUS 0x18121908 ++#define APBZ_S0_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1812190c ++#define APBZ_S0_IDM_IDM_ERROR_LOG_ID 0x18121914 ++#define APBZ_S0_IDM_IDM_ERROR_LOG_FLAGS 0x1812191c ++#define APBZ_S0_IDM_IDM_INTERRUPT_STATUS 0x18121a00 ++#define AXIIC_DS_3_IDM_ERROR_LOG_CONTROL 0x18123900 ++#define AXIIC_DS_3_IDM_ERROR_LOG_COMPLETE 0x18123904 ++#define AXIIC_DS_3_IDM_ERROR_LOG_STATUS 0x18123908 ++#define AXIIC_DS_3_IDM_ERROR_LOG_ADDR_LSB 0x1812390c ++#define AXIIC_DS_3_IDM_ERROR_LOG_ID 0x18123914 ++#define AXIIC_DS_3_IDM_ERROR_LOG_FLAGS 0x1812391c ++#define AXIIC_DS_3_IDM_INTERRUPT_STATUS 0x18123a00 ++#define APBW_IDM_IDM_ERROR_LOG_CONTROL 0x18131900 ++#define APBW_IDM_IDM_ERROR_LOG_COMPLETE 0x18131904 ++#define APBW_IDM_IDM_ERROR_LOG_STATUS 0x18131908 ++#define APBW_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1813190c ++#define APBW_IDM_IDM_ERROR_LOG_ID 0x18131914 ++#define APBW_IDM_IDM_ERROR_LOG_FLAGS 0x1813191c ++#define APBW_IDM_IDM_INTERRUPT_STATUS 0x18131a00 ++#define APBX_IDM_IDM_ERROR_LOG_CONTROL 0x18132900 ++#define APBX_IDM_IDM_ERROR_LOG_COMPLETE 0x18132904 ++#define APBX_IDM_IDM_ERROR_LOG_STATUS 0x18132908 ++#define APBX_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1813290c ++#define APBX_IDM_IDM_ERROR_LOG_ID 0x18132914 ++#define APBX_IDM_IDM_ERROR_LOG_FLAGS 0x1813291c ++#define APBX_IDM_IDM_INTERRUPT_STATUS 0x18132a00 ++#define AXIIC_DS_0_IDM_ERROR_LOG_CONTROL 0x18141900 ++#define AXIIC_DS_0_IDM_ERROR_LOG_COMPLETE 0x18141904 ++#define AXIIC_DS_0_IDM_ERROR_LOG_STATUS 0x18141908 ++#define AXIIC_DS_0_IDM_ERROR_LOG_ADDR_LSB 0x1814190c ++#define AXIIC_DS_0_IDM_ERROR_LOG_ID 0x18141914 ++#define AXIIC_DS_0_IDM_ERROR_LOG_FLAGS 0x1814191c ++#define AXIIC_DS_0_IDM_INTERRUPT_STATUS 0x18141a00 ++ ++#elif defined(CONFIG_MACH_HR3) ++ ++#define IHOST_S0_IDM_ERROR_LOG_CONTROL 0x18107900 ++#define IHOST_S0_IDM_ERROR_LOG_COMPLETE 0x18107904 ++#define IHOST_S0_IDM_ERROR_LOG_STATUS 0x18107908 ++#define IHOST_S0_IDM_ERROR_LOG_ADDR_LSB 0x1810790c ++#define IHOST_S0_IDM_ERROR_LOG_ID 0x18107914 ++#define IHOST_S0_IDM_ERROR_LOG_FLAGS 0x1810791c ++#define IHOST_S0_IDM_INTERRUPT_STATUS 0x18107a00 ++#define IHOST_S1_IDM_ERROR_LOG_CONTROL 0x18106900 ++#define IHOST_S1_IDM_ERROR_LOG_COMPLETE 0x18106904 ++#define IHOST_S1_IDM_ERROR_LOG_STATUS 0x18106908 ++#define IHOST_S1_IDM_ERROR_LOG_ADDR_LSB 0x1810690c ++#define IHOST_S1_IDM_ERROR_LOG_ID 0x18106914 ++#define IHOST_S1_IDM_ERROR_LOG_FLAGS 0x1810691c ++#define IHOST_S1_IDM_INTERRUPT_STATUS 0x18106a00 ++#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_CONTROL 0x18108900 ++#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_COMPLETE 0x18108904 ++#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_STATUS 0x18108908 ++#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1810890c ++#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_ID 0x18108914 ++#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_FLAGS 0x1810891c ++#define AXI_PCIE_S0_IDM_IDM_INTERRUPT_STATUS 0x18108a00 ++#define CMICD_S0_IDM_IDM_ERROR_LOG_CONTROL 0x1810a900 ++#define CMICD_S0_IDM_IDM_ERROR_LOG_COMPLETE 0x1810a904 ++#define CMICD_S0_IDM_IDM_ERROR_LOG_STATUS 0x1810a908 ++#define CMICD_S0_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1810a90c ++#define CMICD_S0_IDM_IDM_ERROR_LOG_ID 0x1810a914 ++#define CMICD_S0_IDM_IDM_ERROR_LOG_FLAGS 0x1810a91c ++#define CMICD_S0_IDM_IDM_INTERRUPT_STATUS 0x1810aa00 ++#define A9JTAG_S0_IDM_IDM_ERROR_LOG_CONTROL 0x18119900 ++#define A9JTAG_S0_IDM_IDM_ERROR_LOG_COMPLETE 0x18119904 ++#define A9JTAG_S0_IDM_IDM_ERROR_LOG_STATUS 0x18119908 ++#define A9JTAG_S0_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1811990c ++#define A9JTAG_S0_IDM_IDM_ERROR_LOG_ID 0x18119914 ++#define A9JTAG_S0_IDM_IDM_ERROR_LOG_FLAGS 0x1811991c ++#define A9JTAG_S0_IDM_IDM_INTERRUPT_STATUS 0x18119a00 ++#define APBX_IDM_IDM_ERROR_LOG_CONTROL 0x18130900 ++#define APBX_IDM_IDM_ERROR_LOG_COMPLETE 0x18130904 ++#define APBX_IDM_IDM_ERROR_LOG_STATUS 0x18130908 ++#define APBX_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1813090c ++#define APBX_IDM_IDM_ERROR_LOG_ID 0x18130914 ++#define APBX_IDM_IDM_ERROR_LOG_FLAGS 0x1813091c ++#define APBX_IDM_IDM_INTERRUPT_STATUS 0x18130a00 ++#define DDR_S1_IDM_ERROR_LOG_CONTROL 0x18104900 ++#define DDR_S1_IDM_ERROR_LOG_COMPLETE 0x18104904 ++#define DDR_S1_IDM_ERROR_LOG_STATUS 0x18104908 ++#define DDR_S1_IDM_ERROR_LOG_ADDR_LSB 0x1810490c ++#define DDR_S1_IDM_ERROR_LOG_ID 0x18104914 ++#define DDR_S1_IDM_ERROR_LOG_FLAGS 0x1810491c ++#define DDR_S1_IDM_INTERRUPT_STATUS 0x18104a00 ++#define DDR_S2_IDM_ERROR_LOG_CONTROL 0x18105900 ++#define DDR_S2_IDM_ERROR_LOG_COMPLETE 0x18105904 ++#define DDR_S2_IDM_ERROR_LOG_STATUS 0x18105908 ++#define DDR_S2_IDM_ERROR_LOG_ADDR_LSB 0x1810590c ++#define DDR_S2_IDM_ERROR_LOG_ID 0x18105914 ++#define DDR_S2_IDM_ERROR_LOG_FLAGS 0x1810591c ++#define DDR_S2_IDM_INTERRUPT_STATUS 0x18105a00 ++#define ROM_S0_IDM_ERROR_LOG_CONTROL 0x1811a900 ++#define ROM_S0_IDM_ERROR_LOG_COMPLETE 0x1811a904 ++#define ROM_S0_IDM_ERROR_LOG_STATUS 0x1811a908 ++#define ROM_S0_IDM_ERROR_LOG_ADDR_LSB 0x1811a90c ++#define ROM_S0_IDM_ERROR_LOG_ID 0x1811a914 ++#define ROM_S0_IDM_ERROR_LOG_FLAGS 0x1811a91c ++#define ROM_S0_IDM_INTERRUPT_STATUS 0x1811aa00 ++#define NAND_IDM_IDM_ERROR_LOG_CONTROL 0x1811d900 ++#define NAND_IDM_IDM_ERROR_LOG_COMPLETE 0x1811d904 ++#define NAND_IDM_IDM_ERROR_LOG_STATUS 0x1811d908 ++#define NAND_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1811d90c ++#define NAND_IDM_IDM_ERROR_LOG_ID 0x1811d914 ++#define NAND_IDM_IDM_ERROR_LOG_FLAGS 0x1811d91c ++#define NAND_IDM_IDM_INTERRUPT_STATUS 0x1811da00 ++#define QSPI_IDM_IDM_ERROR_LOG_CONTROL 0x1811f900 ++#define QSPI_IDM_IDM_ERROR_LOG_COMPLETE 0x1811f904 ++#define QSPI_IDM_IDM_ERROR_LOG_STATUS 0x1811f908 ++#define QSPI_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1811f90c ++#define QSPI_IDM_IDM_ERROR_LOG_ID 0x1811f914 ++#define QSPI_IDM_IDM_ERROR_LOG_FLAGS 0x1811f91c ++#define QSPI_IDM_IDM_INTERRUPT_STATUS 0x1811fa00 ++#define AXIIC_DS_0_IDM_ERROR_LOG_CONTROL 0x18120900 ++#define AXIIC_DS_0_IDM_ERROR_LOG_COMPLETE 0x18120904 ++#define AXIIC_DS_0_IDM_ERROR_LOG_STATUS 0x18120908 ++#define AXIIC_DS_0_IDM_ERROR_LOG_ADDR_LSB 0x1812090c ++#define AXIIC_DS_0_IDM_ERROR_LOG_ID 0x18120914 ++#define AXIIC_DS_0_IDM_ERROR_LOG_FLAGS 0x1812091c ++#define AXIIC_DS_0_IDM_INTERRUPT_STATUS 0x18120a00 ++ ++#elif defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_SB2) || \ ++ defined(CONFIG_MACH_GH2) ++ ++#define IHOST_S0_IDM_ERROR_LOG_CONTROL 0x18107900 ++#define IHOST_S0_IDM_ERROR_LOG_COMPLETE 0x18107904 ++#define IHOST_S0_IDM_ERROR_LOG_STATUS 0x18107908 ++#define IHOST_S0_IDM_ERROR_LOG_ADDR_LSB 0x1810790c ++#define IHOST_S0_IDM_ERROR_LOG_ID 0x18107914 ++#define IHOST_S0_IDM_ERROR_LOG_FLAGS 0x1810791c ++#define IHOST_S0_IDM_INTERRUPT_STATUS 0x18107a00 ++#define IHOST_S1_IDM_ERROR_LOG_CONTROL 0x18106900 ++#define IHOST_S1_IDM_ERROR_LOG_COMPLETE 0x18106904 ++#define IHOST_S1_IDM_ERROR_LOG_STATUS 0x18106908 ++#define IHOST_S1_IDM_ERROR_LOG_ADDR_LSB 0x1810690c ++#define IHOST_S1_IDM_ERROR_LOG_ID 0x18106914 ++#define IHOST_S1_IDM_ERROR_LOG_FLAGS 0x1810691c ++#define IHOST_S1_IDM_INTERRUPT_STATUS 0x18106a00 ++#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_CONTROL 0x18108900 ++#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_COMPLETE 0x18108904 ++#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_STATUS 0x18108908 ++#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1810890c ++#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_ID 0x18108914 ++#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_FLAGS 0x1810891c ++#define AXI_PCIE_S0_IDM_IDM_INTERRUPT_STATUS 0x18108a00 ++#define CMICD_S0_IDM_IDM_ERROR_LOG_CONTROL 0x1810a900 ++#define CMICD_S0_IDM_IDM_ERROR_LOG_COMPLETE 0x1810a904 ++#define CMICD_S0_IDM_IDM_ERROR_LOG_STATUS 0x1810a908 ++#define CMICD_S0_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1810a90c ++#define CMICD_S0_IDM_IDM_ERROR_LOG_ID 0x1810a914 ++#define CMICD_S0_IDM_IDM_ERROR_LOG_FLAGS 0x1810a91c ++#define CMICD_S0_IDM_IDM_INTERRUPT_STATUS 0x1810aa00 ++#define A9JTAG_S0_IDM_IDM_ERROR_LOG_CONTROL 0x18119900 ++#define A9JTAG_S0_IDM_IDM_ERROR_LOG_COMPLETE 0x18119904 ++#define A9JTAG_S0_IDM_IDM_ERROR_LOG_STATUS 0x18119908 ++#define A9JTAG_S0_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1811990c ++#define A9JTAG_S0_IDM_IDM_ERROR_LOG_ID 0x18119914 ++#define A9JTAG_S0_IDM_IDM_ERROR_LOG_FLAGS 0x1811991c ++#define A9JTAG_S0_IDM_IDM_INTERRUPT_STATUS 0x18119a00 ++#define SRAM_S0_IDM_ERROR_LOG_CONTROL 0x1811b900 ++#define SRAM_S0_IDM_ERROR_LOG_COMPLETE 0x1811b904 ++#define SRAM_S0_IDM_ERROR_LOG_STATUS 0x1811b908 ++#define SRAM_S0_IDM_ERROR_LOG_ADDR_LSB 0x1811b90c ++#define SRAM_S0_IDM_ERROR_LOG_ID 0x1811b914 ++#define SRAM_S0_IDM_ERROR_LOG_FLAGS 0x1811b91c ++#define SRAM_S0_IDM_INTERRUPT_STATUS 0x1811ba00 ++#define APBX_IDM_IDM_ERROR_LOG_CONTROL 0x18130900 ++#define APBX_IDM_IDM_ERROR_LOG_COMPLETE 0x18130904 ++#define APBX_IDM_IDM_ERROR_LOG_STATUS 0x18130908 ++#define APBX_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1813090c ++#define APBX_IDM_IDM_ERROR_LOG_ID 0x18130914 ++#define APBX_IDM_IDM_ERROR_LOG_FLAGS 0x1813091c ++#define APBX_IDM_IDM_INTERRUPT_STATUS 0x18130a00 ++#define DDR_S1_IDM_ERROR_LOG_CONTROL 0xf8102900 ++#define DDR_S1_IDM_ERROR_LOG_COMPLETE 0xf8102904 ++#define DDR_S1_IDM_ERROR_LOG_STATUS 0xf8102908 ++#define DDR_S1_IDM_ERROR_LOG_ADDR_LSB 0xf810290c ++#define DDR_S1_IDM_ERROR_LOG_ID 0xf8102914 ++#define DDR_S1_IDM_ERROR_LOG_FLAGS 0xf810291c ++#define DDR_S1_IDM_INTERRUPT_STATUS 0xf8102a00 ++#define DDR_S2_IDM_ERROR_LOG_CONTROL 0xf8103900 ++#define DDR_S2_IDM_ERROR_LOG_COMPLETE 0xf8103904 ++#define DDR_S2_IDM_ERROR_LOG_STATUS 0xf8103908 ++#define DDR_S2_IDM_ERROR_LOG_ADDR_LSB 0xf810390c ++#define DDR_S2_IDM_ERROR_LOG_ID 0xf8103914 ++#define DDR_S2_IDM_ERROR_LOG_FLAGS 0xf810391c ++#define DDR_S2_IDM_INTERRUPT_STATUS 0xf8103a00 ++#define ROM_S0_IDM_ERROR_LOG_CONTROL 0xf8104900 ++#define ROM_S0_IDM_ERROR_LOG_COMPLETE 0xf8104904 ++#define ROM_S0_IDM_ERROR_LOG_STATUS 0xf8104908 ++#define ROM_S0_IDM_ERROR_LOG_ADDR_LSB 0xf810490c ++#define ROM_S0_IDM_ERROR_LOG_ID 0xf8104914 ++#define ROM_S0_IDM_ERROR_LOG_FLAGS 0xf810491c ++#define ROM_S0_IDM_INTERRUPT_STATUS 0xf8104a00 ++#define NAND_IDM_IDM_ERROR_LOG_CONTROL 0xf8105900 ++#define NAND_IDM_IDM_ERROR_LOG_COMPLETE 0xf8105904 ++#define NAND_IDM_IDM_ERROR_LOG_STATUS 0xf8105908 ++#define NAND_IDM_IDM_ERROR_LOG_ADDR_LSB 0xf810590c ++#define NAND_IDM_IDM_ERROR_LOG_ID 0xf8105914 ++#define NAND_IDM_IDM_ERROR_LOG_FLAGS 0xf810591c ++#define NAND_IDM_IDM_INTERRUPT_STATUS 0xf8105a00 ++#define QSPI_IDM_IDM_ERROR_LOG_CONTROL 0xf8106900 ++#define QSPI_IDM_IDM_ERROR_LOG_COMPLETE 0xf8106904 ++#define QSPI_IDM_IDM_ERROR_LOG_STATUS 0xf8106908 ++#define QSPI_IDM_IDM_ERROR_LOG_ADDR_LSB 0xf810690c ++#define QSPI_IDM_IDM_ERROR_LOG_ID 0xf8106914 ++#define QSPI_IDM_IDM_ERROR_LOG_FLAGS 0xf810691c ++#define QSPI_IDM_IDM_INTERRUPT_STATUS 0xf8106a00 ++#define AXIIC_DS_0_IDM_ERROR_LOG_CONTROL 0x18120900 ++#define AXIIC_DS_0_IDM_ERROR_LOG_COMPLETE 0x18120904 ++#define AXIIC_DS_0_IDM_ERROR_LOG_STATUS 0x18120908 ++#define AXIIC_DS_0_IDM_ERROR_LOG_ADDR_LSB 0x1812090c ++#define AXIIC_DS_0_IDM_ERROR_LOG_ID 0x18120914 ++#define AXIIC_DS_0_IDM_ERROR_LOG_FLAGS 0x1812091c ++#define AXIIC_DS_0_IDM_INTERRUPT_STATUS 0x18120a00 ++#if !defined(CONFIG_MACH_GH2) ++#define AXIIC_DS_3_IDM_ERROR_LOG_CONTROL 0x1811e900 ++#define AXIIC_DS_3_IDM_ERROR_LOG_COMPLETE 0x1811e904 ++#define AXIIC_DS_3_IDM_ERROR_LOG_STATUS 0x1811e908 ++#define AXIIC_DS_3_IDM_ERROR_LOG_ADDR_LSB 0x1811e90c ++#define AXIIC_DS_3_IDM_ERROR_LOG_ID 0x1811e914 ++#define AXIIC_DS_3_IDM_ERROR_LOG_FLAGS 0x1811e91c ++#define AXIIC_DS_3_IDM_INTERRUPT_STATUS 0x1811ea00 ++#endif /* !defined(CONFIG_MACH_GH2) */ ++ ++#endif /* defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || \ ++ defined(CONFIG_MACH_HR2) */ ++ ++#if defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_SB2) || \ ++ defined(CONFIG_MACH_GH2) ++#define IDM_IO_PHYS_TO_VIRT(x) (void __iomem *) \ ++ (((x & 0xFFF00000) == (int)get_iproc_idm_base_phys(0))? \ ++ get_iproc_idm_base(0) + x - get_iproc_idm_base_phys(0) : \ ++ get_iproc_idm_base(1) + x - get_iproc_idm_base_phys(1)) ++#else ++#define IDM_IO_PHYS_TO_VIRT(x) (void __iomem *) \ ++ (get_iproc_idm_base(0) + x - get_iproc_idm_base_phys(0)) ++#endif ++ ++ ++#define IHOST_S1_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(IHOST_S1_IDM_ERROR_LOG_CONTROL) ++#define IHOST_S1_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(IHOST_S1_IDM_ERROR_LOG_COMPLETE) ++#define IHOST_S1_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(IHOST_S1_IDM_ERROR_LOG_STATUS) ++#define IHOST_S1_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(IHOST_S1_IDM_ERROR_LOG_ADDR_LSB) ++#define IHOST_S1_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(IHOST_S1_IDM_ERROR_LOG_ID) ++#define IHOST_S1_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(IHOST_S1_IDM_ERROR_LOG_FLAGS) ++ ++#define IHOST_S0_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(IHOST_S0_IDM_ERROR_LOG_CONTROL) ++#define IHOST_S0_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(IHOST_S0_IDM_ERROR_LOG_COMPLETE) ++#define IHOST_S0_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(IHOST_S0_IDM_ERROR_LOG_STATUS) ++#define IHOST_S0_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(IHOST_S0_IDM_ERROR_LOG_ADDR_LSB) ++#define IHOST_S0_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(IHOST_S0_IDM_ERROR_LOG_ID) ++#define IHOST_S0_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(IHOST_S0_IDM_ERROR_LOG_FLAGS) ++ ++#define DDR_S1_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(DDR_S1_IDM_ERROR_LOG_CONTROL) ++#define DDR_S1_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(DDR_S1_IDM_ERROR_LOG_COMPLETE) ++#define DDR_S1_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(DDR_S1_IDM_ERROR_LOG_STATUS) ++#define DDR_S1_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(DDR_S1_IDM_ERROR_LOG_ADDR_LSB) ++#define DDR_S1_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(DDR_S1_IDM_ERROR_LOG_ID) ++#define DDR_S1_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(DDR_S1_IDM_ERROR_LOG_FLAGS) ++ ++#define DDR_S2_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(DDR_S2_IDM_ERROR_LOG_CONTROL) ++#define DDR_S2_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(DDR_S2_IDM_ERROR_LOG_COMPLETE) ++#define DDR_S2_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(DDR_S2_IDM_ERROR_LOG_STATUS) ++#define DDR_S2_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(DDR_S2_IDM_ERROR_LOG_ADDR_LSB) ++#define DDR_S2_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(DDR_S2_IDM_ERROR_LOG_ID) ++#define DDR_S2_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(DDR_S2_IDM_ERROR_LOG_FLAGS) ++ ++#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(AXI_PCIE_S0_IDM_IDM_ERROR_LOG_CONTROL) ++#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(AXI_PCIE_S0_IDM_IDM_ERROR_LOG_COMPLETE) ++#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(AXI_PCIE_S0_IDM_IDM_ERROR_LOG_STATUS) ++#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(AXI_PCIE_S0_IDM_IDM_ERROR_LOG_ADDR_LSB) ++#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(AXI_PCIE_S0_IDM_IDM_ERROR_LOG_ID) ++#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(AXI_PCIE_S0_IDM_IDM_ERROR_LOG_FLAGS) ++ ++#define CMICD_S0_IDM_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(CMICD_S0_IDM_IDM_ERROR_LOG_CONTROL) ++#define CMICD_S0_IDM_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(CMICD_S0_IDM_IDM_ERROR_LOG_COMPLETE) ++#define CMICD_S0_IDM_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(CMICD_S0_IDM_IDM_ERROR_LOG_STATUS) ++#define CMICD_S0_IDM_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(CMICD_S0_IDM_IDM_ERROR_LOG_ADDR_LSB) ++#define CMICD_S0_IDM_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(CMICD_S0_IDM_IDM_ERROR_LOG_ID) ++#define CMICD_S0_IDM_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(CMICD_S0_IDM_IDM_ERROR_LOG_FLAGS) ++ ++#define APBY_S0_IDM_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(APBY_S0_IDM_IDM_ERROR_LOG_CONTROL) ++#define APBY_S0_IDM_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(APBY_S0_IDM_IDM_ERROR_LOG_COMPLETE) ++#define APBY_S0_IDM_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(APBY_S0_IDM_IDM_ERROR_LOG_STATUS) ++#define APBY_S0_IDM_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(APBY_S0_IDM_IDM_ERROR_LOG_ADDR_LSB) ++#define APBY_S0_IDM_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(APBY_S0_IDM_IDM_ERROR_LOG_ID) ++#define APBY_S0_IDM_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(APBY_S0_IDM_IDM_ERROR_LOG_FLAGS) ++ ++#define ROM_S0_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(ROM_S0_IDM_ERROR_LOG_CONTROL) ++#define ROM_S0_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(ROM_S0_IDM_ERROR_LOG_COMPLETE) ++#define ROM_S0_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(ROM_S0_IDM_ERROR_LOG_STATUS) ++#define ROM_S0_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(ROM_S0_IDM_ERROR_LOG_ADDR_LSB) ++#define ROM_S0_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(ROM_S0_IDM_ERROR_LOG_ID) ++#define ROM_S0_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(ROM_S0_IDM_ERROR_LOG_FLAGS) ++ ++#define NAND_IDM_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(NAND_IDM_IDM_ERROR_LOG_CONTROL) ++#define NAND_IDM_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(NAND_IDM_IDM_ERROR_LOG_COMPLETE) ++#define NAND_IDM_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(NAND_IDM_IDM_ERROR_LOG_STATUS) ++#define NAND_IDM_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(NAND_IDM_IDM_ERROR_LOG_ADDR_LSB) ++#define NAND_IDM_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(NAND_IDM_IDM_ERROR_LOG_ID) ++#define NAND_IDM_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(NAND_IDM_IDM_ERROR_LOG_FLAGS) ++ ++#define QSPI_IDM_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(QSPI_IDM_IDM_ERROR_LOG_CONTROL) ++#define QSPI_IDM_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(QSPI_IDM_IDM_ERROR_LOG_COMPLETE) ++#define QSPI_IDM_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(QSPI_IDM_IDM_ERROR_LOG_STATUS) ++#define QSPI_IDM_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(QSPI_IDM_IDM_ERROR_LOG_ADDR_LSB) ++#define QSPI_IDM_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(QSPI_IDM_IDM_ERROR_LOG_ID) ++#define QSPI_IDM_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(QSPI_IDM_IDM_ERROR_LOG_FLAGS) ++ ++#define A9JTAG_S0_IDM_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(A9JTAG_S0_IDM_IDM_ERROR_LOG_CONTROL) ++#define A9JTAG_S0_IDM_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(A9JTAG_S0_IDM_IDM_ERROR_LOG_COMPLETE) ++#define A9JTAG_S0_IDM_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(A9JTAG_S0_IDM_IDM_ERROR_LOG_STATUS) ++#define A9JTAG_S0_IDM_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(A9JTAG_S0_IDM_IDM_ERROR_LOG_ADDR_LSB) ++#define A9JTAG_S0_IDM_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(A9JTAG_S0_IDM_IDM_ERROR_LOG_ID) ++#define A9JTAG_S0_IDM_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(A9JTAG_S0_IDM_IDM_ERROR_LOG_FLAGS) ++ ++#define SRAM_S0_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(SRAM_S0_IDM_ERROR_LOG_CONTROL) ++#define SRAM_S0_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(SRAM_S0_IDM_ERROR_LOG_COMPLETE) ++#define SRAM_S0_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(SRAM_S0_IDM_ERROR_LOG_STATUS) ++#define SRAM_S0_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(SRAM_S0_IDM_ERROR_LOG_ADDR_LSB) ++#define SRAM_S0_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(SRAM_S0_IDM_ERROR_LOG_ID) ++#define SRAM_S0_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(SRAM_S0_IDM_ERROR_LOG_FLAGS) ++ ++#define APBZ_S0_IDM_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(APBZ_S0_IDM_IDM_ERROR_LOG_CONTROL) ++#define APBZ_S0_IDM_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(APBZ_S0_IDM_IDM_ERROR_LOG_COMPLETE) ++#define APBZ_S0_IDM_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(APBZ_S0_IDM_IDM_ERROR_LOG_STATUS) ++#define APBZ_S0_IDM_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(APBZ_S0_IDM_IDM_ERROR_LOG_ADDR_LSB) ++#define APBZ_S0_IDM_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(APBZ_S0_IDM_IDM_ERROR_LOG_ID) ++#define APBZ_S0_IDM_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(APBZ_S0_IDM_IDM_ERROR_LOG_FLAGS) ++ ++#define AXIIC_DS_3_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(AXIIC_DS_3_IDM_ERROR_LOG_CONTROL) ++#define AXIIC_DS_3_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(AXIIC_DS_3_IDM_ERROR_LOG_COMPLETE) ++#define AXIIC_DS_3_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(AXIIC_DS_3_IDM_ERROR_LOG_STATUS) ++#define AXIIC_DS_3_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(AXIIC_DS_3_IDM_ERROR_LOG_ADDR_LSB) ++#define AXIIC_DS_3_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(AXIIC_DS_3_IDM_ERROR_LOG_ID) ++#define AXIIC_DS_3_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(AXIIC_DS_3_IDM_ERROR_LOG_FLAGS) ++ ++#define APBW_IDM_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(APBW_IDM_IDM_ERROR_LOG_CONTROL) ++#define APBW_IDM_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(APBW_IDM_IDM_ERROR_LOG_COMPLETE) ++#define APBW_IDM_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(APBW_IDM_IDM_ERROR_LOG_STATUS) ++#define APBW_IDM_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(APBW_IDM_IDM_ERROR_LOG_ADDR_LSB) ++#define APBW_IDM_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(APBW_IDM_IDM_ERROR_LOG_ID) ++#define APBW_IDM_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(APBW_IDM_IDM_ERROR_LOG_FLAGS) ++ ++#define APBX_IDM_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(APBX_IDM_IDM_ERROR_LOG_CONTROL) ++#define APBX_IDM_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(APBX_IDM_IDM_ERROR_LOG_COMPLETE) ++#define APBX_IDM_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(APBX_IDM_IDM_ERROR_LOG_STATUS) ++#define APBX_IDM_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(APBX_IDM_IDM_ERROR_LOG_ADDR_LSB) ++#define APBX_IDM_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(APBX_IDM_IDM_ERROR_LOG_ID) ++#define APBX_IDM_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(APBX_IDM_IDM_ERROR_LOG_FLAGS) ++ ++#define AXIIC_DS_0_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(AXIIC_DS_0_IDM_ERROR_LOG_CONTROL) ++#define AXIIC_DS_0_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(AXIIC_DS_0_IDM_ERROR_LOG_COMPLETE) ++#define AXIIC_DS_0_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(AXIIC_DS_0_IDM_ERROR_LOG_STATUS) ++#define AXIIC_DS_0_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(AXIIC_DS_0_IDM_ERROR_LOG_ADDR_LSB) ++#define AXIIC_DS_0_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(AXIIC_DS_0_IDM_ERROR_LOG_ID) ++#define AXIIC_DS_0_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(AXIIC_DS_0_IDM_ERROR_LOG_FLAGS) ++ ++#define IDM_ERROR_LOG_ENABLE 0x33A ++#define IDM_ERROR_LOG_CLEAR 0x3 ++ ++#ifdef CONFIG_MACH_IPROC_P7 ++ ++#if defined(CONFIG_MACH_HR3) || defined(CONFIG_MACH_GH2) ++#define IHOST_S0_IDM_IRQ 52 ++#define DDR_S1_IDM_IRQ 53 ++#define DDR_S2_IDM_IRQ 54 ++#define AXI_PCIE_S0_IDM_IRQ 55 ++#define ROM_S0_IDM_IRQ 56 ++#define NAND_IDM_IRQ 57 ++#define QSPI_IDM_IRQ 58 ++#define PNOR_IDM_IRQ 59 ++#define SRAM_S0_IDM_IRQ 60 ++#define A9JTAG_S0_IDM_IRQ 61 ++#define APX_IDM_IRQ 64 ++#define CMICD_S0_IDM_IRQ 67 ++#define AXIIC_DS_0_IDM_IRQ 68 ++#define AXIIC_DS_1_IDM_IRQ 69 ++#define AXIIC_DS_2_IDM_IRQ 70 ++#else ++#define IHOST_S0_IDM_IRQ 52 ++#define DDR_S1_IDM_IRQ 54 ++#define DDR_S2_IDM_IRQ 55 ++#define AXI_PCIE_S0_IDM_IRQ 56 ++#define AXI_PCIE_S1_IDM_IRQ 57 ++#define ROM_S0_IDM_IRQ 58 ++#define NAND_IDM_IRQ 59 ++#define QSPI_IDM_IRQ 60 ++#define SRAM_S0_IDM_IRQ 62 ++#define A9JTAG_S0_IDM_IRQ 64 ++#define APX_IDM_IRQ 68 ++#define CMICD_S0_IDM_IRQ 71 ++#define AXIIC_DS_0_IDM_IRQ 78 ++#define AXIIC_DS_1_IDM_IRQ 79 ++#define AXIIC_DS_2_IDM_IRQ 80 ++#define AXIIC_DS_3_IDM_IRQ 81 ++#endif /* defined(CONFIG_MACH_HR3) || defined(CONFIG_MACH_GH2) */ ++ ++#else /* CONFIG_MACH_IPROC_P7 */ ++ ++#define IHOST_S1_IDM_IRQ 62 ++#define IHOST_S0_IDM_IRQ 63 ++#define DDR_S1_IDM_IRQ 64 ++#define DDR_S2_IDM_IRQ 65 ++#define AXI_PCIE_S0_IDM_IRQ 66 ++#define AXI_PCIE_S1_IDM_IRQ 67 ++#define CMICD_S0_IDM_IRQ 68 ++#define ROM_S0_IDM_IRQ 69 ++#define NAND_IDM_IRQ 70 ++#define QSPI_IDM_IRQ 71 ++#define A9JTAG_S0_IDM_IRQ 73 ++#define SRAM_S0_IDM_IRQ 74 ++#define APW_IDM_IRQ 75 ++#define APX_IDM_IRQ 76 ++#define APBY_S0_IDM_IRQ 77 ++#define APBZ_S0_IDM_IRQ 78 ++#define AXIIC_DS_0_IDM_IRQ 79 ++#define AXIIC_DS_1_IDM_IRQ 80 ++#define AXIIC_DS_2_IDM_IRQ 81 ++#define AXIIC_DS_3_IDM_IRQ 82 ++#define AXIIC_DS_4_IDM_IRQ 83 ++ ++#endif /* CONFIG_MACH_IPROC_P7 */ ++ ++static irqreturn_t idm_timeout_handler(int val, void *ptr) ++{ ++ u32 errval; ++ ++ printk(KERN_DEBUG "%s: %d, %d entry\n", __func__, __LINE__, val); ++ errval = readl(IHOST_S1_IDM_ERROR_LOG_STATUS_VA); ++ if (errval > 0) ++ { ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ errval = readl(IHOST_S1_IDM_ERROR_LOG_ADDR_LSB_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(IHOST_S1_IDM_ERROR_LOG_ID_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(IHOST_S1_IDM_ERROR_LOG_FLAGS_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ writel(IDM_ERROR_LOG_CLEAR, IHOST_S1_IDM_ERROR_LOG_COMPLETE_VA); ++ errval = readl(IHOST_S1_IDM_ERROR_LOG_STATUS_VA); ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ } ++ errval = readl(IHOST_S0_IDM_ERROR_LOG_STATUS_VA); ++ if (errval > 0) ++ { ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ errval = readl(IHOST_S0_IDM_ERROR_LOG_ADDR_LSB_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(IHOST_S0_IDM_ERROR_LOG_ID_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(IHOST_S0_IDM_ERROR_LOG_FLAGS_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ writel(IDM_ERROR_LOG_CLEAR, IHOST_S0_IDM_ERROR_LOG_COMPLETE_VA); ++ errval = readl(IHOST_S0_IDM_ERROR_LOG_STATUS_VA); ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ } ++ errval = readl(DDR_S1_IDM_ERROR_LOG_STATUS_VA); ++ if (errval > 0) ++ { ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ errval = readl(DDR_S1_IDM_ERROR_LOG_ADDR_LSB_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(DDR_S1_IDM_ERROR_LOG_ID_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(DDR_S1_IDM_ERROR_LOG_FLAGS_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ writel(IDM_ERROR_LOG_CLEAR, DDR_S1_IDM_ERROR_LOG_COMPLETE_VA); ++ errval = readl(DDR_S1_IDM_ERROR_LOG_STATUS_VA); ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ } ++ errval = readl(DDR_S2_IDM_ERROR_LOG_STATUS_VA); ++ if (errval > 0) ++ { ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ errval = readl(DDR_S2_IDM_ERROR_LOG_ADDR_LSB_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(DDR_S2_IDM_ERROR_LOG_ID_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(DDR_S2_IDM_ERROR_LOG_FLAGS_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ writel(IDM_ERROR_LOG_CLEAR, DDR_S2_IDM_ERROR_LOG_COMPLETE_VA); ++ errval = readl(DDR_S2_IDM_ERROR_LOG_STATUS_VA); ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ } ++ errval = readl(AXI_PCIE_S0_IDM_IDM_ERROR_LOG_STATUS_VA); ++ if (errval > 0) ++ { ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ errval = readl(AXI_PCIE_S0_IDM_IDM_ERROR_LOG_ADDR_LSB_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(AXI_PCIE_S0_IDM_IDM_ERROR_LOG_ID_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(AXI_PCIE_S0_IDM_IDM_ERROR_LOG_FLAGS_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ writel(IDM_ERROR_LOG_CLEAR, AXI_PCIE_S0_IDM_IDM_ERROR_LOG_COMPLETE_VA); ++ errval = readl(AXI_PCIE_S0_IDM_IDM_ERROR_LOG_STATUS_VA); ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ } ++ errval = readl(CMICD_S0_IDM_IDM_ERROR_LOG_STATUS_VA); ++ if (errval > 0) ++ { ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ errval = readl(CMICD_S0_IDM_IDM_ERROR_LOG_ADDR_LSB_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(CMICD_S0_IDM_IDM_ERROR_LOG_ID_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(CMICD_S0_IDM_IDM_ERROR_LOG_FLAGS_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ writel(IDM_ERROR_LOG_CLEAR, CMICD_S0_IDM_IDM_ERROR_LOG_COMPLETE_VA); ++ errval = readl(CMICD_S0_IDM_IDM_ERROR_LOG_STATUS_VA); ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ } ++#if !defined(CONFIG_MACH_IPROC_P7) ++ errval = readl(APBY_S0_IDM_IDM_ERROR_LOG_STATUS_VA); ++ if (errval > 0) ++ { ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ errval = readl(APBY_S0_IDM_IDM_ERROR_LOG_ADDR_LSB_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(APBY_S0_IDM_IDM_ERROR_LOG_ID_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(APBY_S0_IDM_IDM_ERROR_LOG_FLAGS_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ writel(IDM_ERROR_LOG_CLEAR, APBY_S0_IDM_IDM_ERROR_LOG_COMPLETE_VA); ++ errval = readl(APBY_S0_IDM_IDM_ERROR_LOG_STATUS_VA); ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ } ++#endif ++ errval = readl(ROM_S0_IDM_ERROR_LOG_STATUS_VA); ++ if (errval > 0) ++ { ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ errval = readl(ROM_S0_IDM_ERROR_LOG_ADDR_LSB_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(ROM_S0_IDM_ERROR_LOG_ID_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(ROM_S0_IDM_ERROR_LOG_FLAGS_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ writel(IDM_ERROR_LOG_CLEAR, ROM_S0_IDM_ERROR_LOG_COMPLETE_VA); ++ errval = readl(ROM_S0_IDM_ERROR_LOG_STATUS_VA); ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ } ++ errval = readl(NAND_IDM_IDM_ERROR_LOG_STATUS_VA); ++ if (errval > 0) ++ { ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ errval = readl(NAND_IDM_IDM_ERROR_LOG_ADDR_LSB_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(NAND_IDM_IDM_ERROR_LOG_ID_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(NAND_IDM_IDM_ERROR_LOG_FLAGS_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ writel(IDM_ERROR_LOG_CLEAR, NAND_IDM_IDM_ERROR_LOG_COMPLETE_VA); ++ errval = readl(NAND_IDM_IDM_ERROR_LOG_STATUS_VA); ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ } ++ errval = readl(QSPI_IDM_IDM_ERROR_LOG_STATUS_VA); ++ if (errval > 0) ++ { ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ errval = readl(QSPI_IDM_IDM_ERROR_LOG_ADDR_LSB_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(QSPI_IDM_IDM_ERROR_LOG_ID_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(QSPI_IDM_IDM_ERROR_LOG_FLAGS_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ writel(IDM_ERROR_LOG_CLEAR, QSPI_IDM_IDM_ERROR_LOG_COMPLETE_VA); ++ errval = readl(QSPI_IDM_IDM_ERROR_LOG_STATUS_VA); ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ } ++ errval = readl(A9JTAG_S0_IDM_IDM_ERROR_LOG_STATUS_VA); ++ if (errval > 0) ++ { ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ errval = readl(A9JTAG_S0_IDM_IDM_ERROR_LOG_ADDR_LSB_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(A9JTAG_S0_IDM_IDM_ERROR_LOG_ID_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(A9JTAG_S0_IDM_IDM_ERROR_LOG_FLAGS_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ writel(IDM_ERROR_LOG_CLEAR, A9JTAG_S0_IDM_IDM_ERROR_LOG_COMPLETE_VA); ++ errval = readl(A9JTAG_S0_IDM_IDM_ERROR_LOG_STATUS_VA); ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ } ++#if !defined(CONFIG_MACH_IPROC_P7) ++ errval = readl(SRAM_S0_IDM_ERROR_LOG_STATUS_VA); ++ if (errval > 0) ++ { ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ errval = readl(SRAM_S0_IDM_ERROR_LOG_ADDR_LSB_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(SRAM_S0_IDM_ERROR_LOG_ID_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(SRAM_S0_IDM_ERROR_LOG_FLAGS_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ writel(IDM_ERROR_LOG_CLEAR, SRAM_S0_IDM_ERROR_LOG_COMPLETE_VA); ++ errval = readl(SRAM_S0_IDM_ERROR_LOG_STATUS_VA); ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ } ++ errval = readl(APBZ_S0_IDM_IDM_ERROR_LOG_STATUS_VA); ++ if (errval > 0) ++ { ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ errval = readl(APBZ_S0_IDM_IDM_ERROR_LOG_ADDR_LSB_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(APBZ_S0_IDM_IDM_ERROR_LOG_ID_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(APBZ_S0_IDM_IDM_ERROR_LOG_FLAGS_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ writel(IDM_ERROR_LOG_CLEAR, APBZ_S0_IDM_IDM_ERROR_LOG_COMPLETE_VA); ++ errval = readl(APBZ_S0_IDM_IDM_ERROR_LOG_STATUS_VA); ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ } ++#endif ++ ++#if !defined(CONFIG_MACH_HR3) && !defined(CONFIG_MACH_GH2) ++ errval = readl(AXIIC_DS_3_IDM_ERROR_LOG_STATUS_VA); ++ if (errval > 0) ++ { ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ errval = readl(AXIIC_DS_3_IDM_ERROR_LOG_ADDR_LSB_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(AXIIC_DS_3_IDM_ERROR_LOG_ID_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(AXIIC_DS_3_IDM_ERROR_LOG_FLAGS_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ writel(IDM_ERROR_LOG_CLEAR, AXIIC_DS_3_IDM_ERROR_LOG_COMPLETE_VA); ++ errval = readl(AXIIC_DS_3_IDM_ERROR_LOG_STATUS_VA); ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ } ++#endif /* !defined(CONFIG_MACH_HR3) && !defined(CONFIG_MACH_GH2)*/ ++ ++#if !defined(CONFIG_MACH_IPROC_P7) ++ errval = readl(APBW_IDM_IDM_ERROR_LOG_STATUS_VA); ++ if (errval > 0) ++ { ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ errval = readl(APBW_IDM_IDM_ERROR_LOG_ADDR_LSB_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(APBW_IDM_IDM_ERROR_LOG_ID_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(APBW_IDM_IDM_ERROR_LOG_FLAGS_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ writel(IDM_ERROR_LOG_CLEAR, APBW_IDM_IDM_ERROR_LOG_COMPLETE_VA); ++ errval = readl(APBW_IDM_IDM_ERROR_LOG_STATUS_VA); ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ } ++#endif ++ errval = readl(APBX_IDM_IDM_ERROR_LOG_STATUS_VA); ++ if (errval > 0) ++ { ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ errval = readl(APBX_IDM_IDM_ERROR_LOG_ADDR_LSB_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(APBX_IDM_IDM_ERROR_LOG_ID_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(APBX_IDM_IDM_ERROR_LOG_FLAGS_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ writel(IDM_ERROR_LOG_CLEAR, APBX_IDM_IDM_ERROR_LOG_COMPLETE_VA); ++ errval = readl(APBX_IDM_IDM_ERROR_LOG_STATUS_VA); ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ } ++ errval = readl(AXIIC_DS_0_IDM_ERROR_LOG_STATUS_VA); ++ if (errval > 0) ++ { ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ errval = readl(AXIIC_DS_0_IDM_ERROR_LOG_ADDR_LSB_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(AXIIC_DS_0_IDM_ERROR_LOG_ID_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ errval = readl(AXIIC_DS_0_IDM_ERROR_LOG_FLAGS_VA); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); ++ writel(IDM_ERROR_LOG_CLEAR, AXIIC_DS_0_IDM_ERROR_LOG_COMPLETE_VA); ++ errval = readl(AXIIC_DS_0_IDM_ERROR_LOG_STATUS_VA); ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++void init_request_idm_timeout(void) ++{ ++ /* clear all pending idm interrupts */ ++ idm_timeout_handler(0, NULL); ++ ++ /* enable idm error log for all slaves */ ++ ++ writel(IDM_ERROR_LOG_ENABLE, IHOST_S1_IDM_ERROR_LOG_CONTROL_VA); ++ writel(IDM_ERROR_LOG_ENABLE, IHOST_S0_IDM_ERROR_LOG_COMPLETE_VA); ++ writel(IDM_ERROR_LOG_ENABLE, DDR_S1_IDM_ERROR_LOG_COMPLETE_VA); ++ writel(IDM_ERROR_LOG_ENABLE, DDR_S2_IDM_ERROR_LOG_COMPLETE_VA); ++ writel(IDM_ERROR_LOG_ENABLE, AXI_PCIE_S0_IDM_IDM_ERROR_LOG_CONTROL_VA); ++ writel(IDM_ERROR_LOG_ENABLE, CMICD_S0_IDM_IDM_ERROR_LOG_CONTROL_VA); ++ ++#if !defined(CONFIG_MACH_HR3) && !defined(CONFIG_MACH_GH2) ++ writel(IDM_ERROR_LOG_ENABLE, SRAM_S0_IDM_ERROR_LOG_CONTROL_VA); ++#endif /* !defined(CONFIG_MACH_HR3) && !defined(CONFIG_MACH_GH2)*/ ++ ++#ifndef CONFIG_MACH_IPROC_P7 ++ writel(IDM_ERROR_LOG_ENABLE, APBY_S0_IDM_IDM_ERROR_LOG_CONTROL_VA); ++ writel(IDM_ERROR_LOG_ENABLE, APBZ_S0_IDM_IDM_ERROR_LOG_CONTROL_VA); ++ writel(IDM_ERROR_LOG_ENABLE, APBW_IDM_IDM_ERROR_LOG_CONTROL_VA); ++#endif ++ ++ writel(IDM_ERROR_LOG_ENABLE, ROM_S0_IDM_ERROR_LOG_CONTROL_VA); ++ writel(IDM_ERROR_LOG_ENABLE, NAND_IDM_IDM_ERROR_LOG_CONTROL_VA); ++ writel(IDM_ERROR_LOG_ENABLE, QSPI_IDM_IDM_ERROR_LOG_CONTROL_VA); ++ writel(IDM_ERROR_LOG_ENABLE, A9JTAG_S0_IDM_IDM_ERROR_LOG_CONTROL_VA); ++#if !defined(CONFIG_MACH_HR3) && !defined(CONFIG_MACH_GH2) ++ writel(IDM_ERROR_LOG_ENABLE, AXIIC_DS_3_IDM_ERROR_LOG_COMPLETE_VA); ++#endif /* !defined(CONFIG_MACH_HR3) && !defined(CONFIG_MACH_GH2) */ ++ writel(IDM_ERROR_LOG_ENABLE, APBX_IDM_IDM_ERROR_LOG_CONTROL_VA); ++ writel(IDM_ERROR_LOG_ENABLE, AXIIC_DS_0_IDM_ERROR_LOG_CONTROL_VA); ++} ++ ++int request_idm_timeout_interrupts(struct device_node *np) ++{ ++ int i, ret, irq; ++ unsigned int irqs_total; ++ ++ init_request_idm_timeout(); ++ ++ irqs_total = of_irq_count(np); ++ if (!irqs_total) ++ return -EINVAL; ++ ++ for (i=0; i ++#include ++#include ++#include ++ ++#define IPROC_DMU_PCU_COMPATIBLE "brcm,iproc-dmu-pcu" ++#define IPROC_WRAP_CTRL_COMPATIBLE "brcm,iproc-wrap-ctrl" ++#define IPROC_IDM_COMPATIBLE "brcm,iproc-idm" ++#define MAX_IDM_NUM 2 ++ ++static void __iomem *iproc_dmu_pcu_base=NULL; ++static void __iomem *iproc_wrap_ctrl_base=NULL; ++static void __iomem *iproc_idm_base[MAX_IDM_NUM]={NULL}; ++static void __iomem *iproc_idm_base_phys[MAX_IDM_NUM]={NULL}; ++ ++ ++extern void request_idm_timeout_interrupts(struct device_node *); ++ ++void inline __iomem *get_iproc_dmu_pcu_base(void) { ++ return iproc_dmu_pcu_base; ++} ++ ++void inline __iomem *get_iproc_wrap_ctrl_base(void) { ++ return iproc_wrap_ctrl_base; ++} ++ ++void inline __iomem *get_iproc_idm_base(int index) { ++ return iproc_idm_base[index]; ++} ++ ++void inline __iomem *get_iproc_idm_base_phys(int index) { ++ return iproc_idm_base_phys[index]; ++} ++ ++int xgs_iproc_wrap_idm_dmu_base_reg_setup(void) ++{ ++ struct device_node *np; ++ ++ /* Get DMU/PCU base addr */ ++ np = of_find_compatible_node(NULL, NULL, IPROC_DMU_PCU_COMPATIBLE); ++ if (!np) { ++ pr_err("%s: No dmu/pcu node found\n", __func__); ++ return -ENODEV ; ++ } ++ iproc_dmu_pcu_base = of_iomap(np, 0); ++ if (!iproc_dmu_pcu_base) ++ return -ENOMEM; ++ ++ /* Get WRAP CTRL base addr */ ++ np = of_find_compatible_node(NULL, NULL, IPROC_WRAP_CTRL_COMPATIBLE); ++ if (!np) { ++ pr_err("%s: No wrap ctrl node found\n", __func__); ++ return -ENODEV; ++ } ++ iproc_wrap_ctrl_base = of_iomap(np, 0); ++ if (!iproc_wrap_ctrl_base) ++ return -ENOMEM; ++ ++ /* Get IDM base addr */ ++ np = of_find_compatible_node(NULL, NULL, IPROC_IDM_COMPATIBLE); ++ if (!np) { ++ pr_err("%s: No IDM node found\n", __func__); ++ return -ENODEV; ++ } ++ iproc_idm_base[0] = of_iomap(np, 0); ++ if (!iproc_idm_base[0]) ++ return -ENOMEM; ++ ++ /* Second IDM base addr required for GH/SB2/GH2 IDM timeout handling. ++ * For other devices, the second IDM base addr is not used. So, it is ++ * fine even the addr is NULL. ++ */ ++ iproc_idm_base[1] = of_iomap(np, 1); ++ ++ return 1; ++} ++ ++void xgs_iproc_idm_timeout_handler_setup(void) ++{ ++ struct device_node *np; ++ struct platform_device *pdev=NULL; ++ struct resource *res_mem; ++ ++ /* To get IDM phys addr */ ++ np = of_find_compatible_node(NULL, NULL, IPROC_IDM_COMPATIBLE); ++ if (!np) { ++ pr_warn("%s: No IDM node found\n", __func__); ++ return; ++ } ++ pdev = of_find_device_by_node(np); ++ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!res_mem) { ++ pr_warn("%s: No resource found\n", __func__); ++ return; ++ } ++ iproc_idm_base_phys[0] = (void __iomem *)res_mem->start; ++ ++ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); ++ /* Only GH/SB2/GH2 has second IDM base addr */ ++ if (res_mem) ++ iproc_idm_base_phys[1] = (void __iomem *)res_mem->start; ++ ++ /* register IDM timeout interrupt handler */ ++ request_idm_timeout_interrupts(np); ++} +\ No newline at end of file +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/spi/Kconfig b/drivers/spi/Kconfig +--- a/drivers/spi/Kconfig 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/spi/Kconfig 2017-11-09 17:53:55.798375000 +0800 +@@ -654,6 +654,74 @@ config SPI_NUC900 + help + SPI driver for Nuvoton NUC900 series ARM SoCs + ++config SPI_XGS_IPROC ++ tristate "BRCM XGS iProc QSPI support" ++ depends on ARCH_XGS_IPROC ++ default n ++ help ++ This selects a driver for the iProc QSPI Controller (for serial flash). ++ ++ If unsure, say N. ++ ++if SPI_XGS_IPROC ++ ++choice ++ prompt "Multi I/O SPI support" ++ default IPROC_QSPI_SINGLE_MODE ++ help ++ Number of (multi I/O) data lanes supported by the SPI flash. ++ ++config IPROC_QSPI_SINGLE_MODE ++ bool "Single lane" ++ help ++ Single lane. ++ ++config IPROC_QSPI_DUAL_MODE ++ bool "Dual mode" ++ help ++ Dual mode. ++ ++config IPROC_QSPI_QUAD_MODE ++ bool "Quad mode" ++ help ++ Quad mode. ++ ++endchoice ++ ++config IPROC_QSPI_MULTI_LANE_ADDR ++ bool "Use multi lanes also for address" ++ depends on IPROC_QSPI_DUAL_MODE || IPROC_QSPI_QUAD_MODE ++ default y ++ help ++ Use multi lanes also for address. ++ ++config IPROC_QSPI_READ_CMD ++ hex "Flash opcode for multi I/O read" ++ depends on IPROC_QSPI_DUAL_MODE || IPROC_QSPI_QUAD_MODE ++ range 0x00 0xff ++ default 0xbb if IPROC_QSPI_DUAL_MODE ++ default 0xeb ++ help ++ Flash opcode to send to flash for multip I/O read. ++ ++config IPROC_QSPI_READ_DUMMY_CYCLES ++ int "Dummy cycles for multi I/O read operation" ++ depends on IPROC_QSPI_DUAL_MODE || IPROC_QSPI_QUAD_MODE ++ range 0 255 ++ default 8 if IPROC_QSPI_DUAL_MODE ++ default 10 ++ help ++ Dummy cycles for flash read operation ++ ++config IPROC_QSPI_MAX_HZ ++ int "Maximal SPI clock in HZ" ++ range 1 1000000000 ++ default 62500000 ++ help ++ The maximal SPI clock (in Hz) supported by the flash. ++ ++endif # SPI_XGS_IPROC ++ + # + # Add new SPI master controllers in alphabetical order above this line + # +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/spi/Makefile b/drivers/spi/Makefile +--- a/drivers/spi/Makefile 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/spi/Makefile 2017-11-09 17:53:55.799375000 +0800 +@@ -93,3 +93,5 @@ obj-$(CONFIG_SPI_XILINX) += spi-xilinx. + obj-$(CONFIG_SPI_XLP) += spi-xlp.o + obj-$(CONFIG_SPI_XTENSA_XTFPGA) += spi-xtensa-xtfpga.o + obj-$(CONFIG_SPI_ZYNQMP_GQSPI) += spi-zynqmp-gqspi.o ++obj-$(CONFIG_SPI_XGS_IPROC) += spi-xgs-iproc.o ++ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/spi/spi-xgs-iproc.c b/drivers/spi/spi-xgs-iproc.c +--- a/drivers/spi/spi-xgs-iproc.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/spi/spi-xgs-iproc.c 2017-11-09 17:53:55.932382000 +0800 +@@ -0,0 +1,1982 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef CONFIG_OF ++#include ++#include ++#include ++#include ++#endif ++ ++#define DBG(...) /* */ ++ ++/* ++ * Interrupts ++ */ ++ ++#define QSPI_INTR_COUNT (7) ++ ++#define QSPI_INTR_MSPI_HALTED_MASK (0x00000040) ++#define QSPI_INTR_MSPI_DONE_MASK (0x00000020) ++#define QSPI_INTR_BSPI_LR_OVERREAD_MASK (0x00000010) ++#define QSPI_INTR_BSPI_LR_SESSION_DONE_MASK (0x00000008) ++#define QSPI_INTR_BSPI_LR_IMPATIENT_MASK (0x00000004) ++#define QSPI_INTR_BSPI_LR_SESSION_ABORTED_MASK (0x00000002) ++#define QSPI_INTR_BSPI_LR_FULLNESS_REACHED_MASK (0x00000001) ++ ++#define BSPI_LR_INTERRUPTS_DATA \ ++ (QSPI_INTR_BSPI_LR_SESSION_DONE_MASK | \ ++ QSPI_INTR_BSPI_LR_FULLNESS_REACHED_MASK) ++ ++#define BSPI_LR_INTERRUPTS_ERROR \ ++ (QSPI_INTR_BSPI_LR_OVERREAD_MASK | \ ++ QSPI_INTR_BSPI_LR_IMPATIENT_MASK | \ ++ QSPI_INTR_BSPI_LR_SESSION_ABORTED_MASK) ++ ++#define BSPI_LR_INTERRUPTS_ALL \ ++ (BSPI_LR_INTERRUPTS_ERROR | \ ++ BSPI_LR_INTERRUPTS_DATA) ++ ++#define SPBR_MIN 8U ++#define SPBR_MAX 255U ++#define DEFAULT_SPEED_HZ 25000000UL ++#define MSPI_REFCLK_SOURCE "c_clk125" /* To be doubled */ ++#define MSPI_REFCLK_SOURCE_DEVID "iproc_slow" ++ ++/* ++ * Flash opcode and parameters ++ */ ++#define OPCODE_RDID 0x9f ++#define OPCODE_WREN 0x06 ++#define OPCODE_WRDI 0x04 ++#define OPCODE_WRR 0x01 ++#define OPCODE_RCR 0x35 ++#define OPCODE_READ 0x03 ++#define OPCODE_RDSR 0x05 ++#define OPCODE_WRSR 0x01 ++#define OPCODE_RDFSR 0x70 ++#define OPCODE_FAST_READ 0x0B ++#define OPCODE_FAST_READ_4B 0x0C ++#define OPCODE_EN4B 0xB7 ++#define OPCODE_EX4B 0xE9 ++#define OPCODE_BRWR 0x17 ++ ++#define BSPI_WIDTH_1BIT 1 ++#define BSPI_WIDTH_2BIT 2 ++#define BSPI_WIDTH_4BIT 4 ++ ++#define BSPI_ADDRLEN_3BYTES 3 ++#define BSPI_ADDRLEN_4BYTES 4 ++ ++#define BSPI_FLASH_TYPE_SPANSION 0 ++#define BSPI_FLASH_TYPE_MACRONIX 1 ++#define BSPI_FLASH_TYPE_NUMONYX 2 ++#define BSPI_FLASH_TYPE_SST 3 ++#define BSPI_FLASH_TYPE_UNKNOWN -1 ++ ++/* ++ * Register masks/fields/values ++ */ ++#define QSPI_BSPI_RAF_STATUS_FIFO_EMPTY_MASK (0x00000002) ++#define QSPI_BSPI_RAF_CONTROL_START_MASK (0x00000001) ++#define QSPI_BSPI_RAF_CONTROL_CLEAR_MASK (0x00000002) ++#define QSPI_BSPI_BPP_ADDR_BPP_SELECT_MASK (0x00010000) ++#define QSPI_BSPI_BPP_MODE_BPP_MASK (0x00000100) ++#define QSPI_BSPI_FLEX_MODE_ENABLE_MASK (0x00000001) ++ ++ ++/* ++ * Module parameters ++ */ ++ ++/* Mulit I/O for read: 0 - single, 1 - dual, 2 - quad */ ++#ifdef CONFIG_IPROC_QSPI_SINGLE_MODE ++static int io_mode = 0; ++#else /* !CONFIG_IPROC_QSPI_SINGLE_MODE */ ++#ifdef CONFIG_IPROC_QSPI_DUAL_MODE ++static int io_mode = 1; ++#else /* !CONFIG_IPROC_QSPI_DUAL_MODE */ ++static int io_mode = 2; ++#endif /* !CONFIG_IPROC_QSPI_DUAL_MODE */ ++#endif /* !CONFIG_IPROC_QSPI_SINGLE_MODE */ ++module_param(io_mode, int, 0444); ++ ++/* Multi I/O for address (only if not in single mode) */ ++#ifdef CONFIG_IPROC_QSPI_MULTI_LANE_ADDR ++static int addr_multi = 1; ++#else /* !CONFIG_IPROC_QSPI_MULTI_LANE_ADDR */ ++static int addr_multi = 0; ++#endif /* !CONFIG_IPROC_QSPI_MULTI_LANE_ADDR */ ++module_param(addr_multi, int, 0444); ++ ++/* Read opcode (only if not in single mode) */ ++#ifdef CONFIG_IPROC_QSPI_SINGLE_MODE ++static int read_opcode = OPCODE_FAST_READ; ++#else /* !CONFIG_IPROC_QSPI_SINGLE_MODE */ ++static int read_opcode = CONFIG_IPROC_QSPI_READ_CMD; ++#endif /* !CONFIG_IPROC_QSPI_SINGLE_MODE */ ++module_param(read_opcode, int, 0444); ++ ++/* Dummy cycles for read (only if not in single mode) */ ++#ifdef CONFIG_IPROC_QSPI_SINGLE_MODE ++static int dummy_cycles = 8; ++#else /* !CONFIG_IPROC_QSPI_SINGLE_MODE */ ++static int dummy_cycles = CONFIG_IPROC_QSPI_READ_DUMMY_CYCLES; ++#endif /* !CONFIG_IPROC_QSPI_SINGLE_MODE */ ++module_param(dummy_cycles, int, 0444); ++ ++/* Max SPI clock HZ */ ++static int max_hz = 0; ++module_param(max_hz, int, 0444); ++ ++/* Spansion high performance mode */ ++static int bspi_hp; ++module_param(bspi_hp, int, 0444); ++ ++struct brcmspi_platform_data { ++ int flash_cs; ++}; ++ ++struct bcmspi_parms { ++ u32 speed_hz; ++ u8 chip_select; ++ u8 mode; ++ u8 bits_per_word; ++}; ++ ++struct position { ++ struct spi_message *msg; ++ struct spi_transfer *trans; ++ int byte; ++ int mspi_16bit; ++}; ++ ++#define NUM_TXRAM 32 ++#define NUM_RXRAM 32 ++#define NUM_CDRAM 16 ++ ++struct bcm_mspi_hw { ++ u32 spcr0_lsb; /* 0x000 */ ++ u32 spcr0_msb; /* 0x004 */ ++ u32 spcr1_lsb; /* 0x008 */ ++ u32 spcr1_msb; /* 0x00c */ ++ u32 newqp; /* 0x010 */ ++ u32 endqp; /* 0x014 */ ++ u32 spcr2; /* 0x018 */ ++ u32 reserved0; /* 0x01c */ ++ u32 mspi_status; /* 0x020 */ ++ u32 cptqp; /* 0x024 */ ++ u32 reserved1[6]; /* 0x028 */ ++ u32 txram[NUM_TXRAM]; /* 0x040 */ ++ u32 rxram[NUM_RXRAM]; /* 0x0c0 */ ++ u32 cdram[NUM_CDRAM]; /* 0x140 */ ++ u32 write_lock; /* 0x180 */ ++ u32 disable_flush_gen; /* 0x184 */ ++}; ++ ++struct bcm_bspi_hw { ++ u32 revision_id; /* 0x000 */ ++ u32 scratch; /* 0x004 */ ++ u32 mast_n_boot_ctrl; /* 0x008 */ ++ u32 busy_status; /* 0x00c */ ++ u32 intr_status; /* 0x010 */ ++ u32 b0_status; /* 0x014 */ ++ u32 b0_ctrl; /* 0x018 */ ++ u32 b1_status; /* 0x01c */ ++ u32 b1_ctrl; /* 0x020 */ ++ u32 strap_override_ctrl; /* 0x024 */ ++ u32 flex_mode_enable; /* 0x028 */ ++ u32 bits_per_cycle; /* 0x02C */ ++ u32 bits_per_phase; /* 0x030 */ ++ u32 cmd_and_mode_byte; /* 0x034 */ ++ u32 flash_upper_addr_byte; /* 0x038 */ ++ u32 xor_value; /* 0x03C */ ++ u32 xor_enable; /* 0x040 */ ++ u32 pio_mode_enable; /* 0x044 */ ++ u32 pio_iodir; /* 0x048 */ ++ u32 pio_data; /* 0x04C */ ++}; ++ ++struct bcm_bspi_raf { ++ u32 start_address; /* 0x00 */ ++ u32 num_words; /* 0x04 */ ++ u32 ctrl; /* 0x08 */ ++ u32 fullness; /* 0x0C */ ++ u32 watermark; /* 0x10 */ ++ u32 status; /* 0x14 */ ++ u32 read_data; /* 0x18 */ ++ u32 word_cnt; /* 0x1C */ ++ u32 curr_addr; /* 0x20 */ ++}; ++ ++struct bcm_idm_qspi_ctrl { ++ u32 io_ctrl_direct; ++}; ++ ++struct bcm_cru_control { ++ u32 cru_control; ++}; ++ ++struct bcm_flex_mode { ++ int width; ++ int addrlen; ++ int hp; ++}; ++ ++#define STATE_IDLE 0 ++#define STATE_RUNNING 1 ++#define STATE_SHUTDOWN 2 ++ ++struct bcmspi_priv { ++ struct platform_device *pdev; ++ struct spi_master *master; ++ spinlock_t lock; ++ struct bcmspi_parms last_parms; ++ struct position pos; ++ struct list_head msg_queue; ++ int state; ++ int outstanding_bytes; ++ int next_udelay; ++ int cs_change; ++ unsigned int mspi_refclk; ++ unsigned int max_speed_hz; ++ volatile struct bcm_mspi_hw *mspi_hw; ++ int irq; ++ struct tasklet_struct tasklet; ++ int curr_cs; ++ ++ /* BSPI */ ++ volatile struct bcm_bspi_hw *bspi_hw; ++ volatile struct bcm_cru_control *cru_hw; ++ int bspi_enabled; ++ /* all chip selects controlled by BSPI */ ++ int bspi_chip_select; ++ ++ /* LR */ ++ volatile struct bcm_bspi_raf *bspi_hw_raf; ++ struct spi_transfer *cur_xfer; ++ u32 cur_xfer_idx; ++ u32 cur_xfer_len; ++ u32 xfer_status; ++ struct spi_message *cur_msg; ++ u32 actual_length; ++ u32 raf_next_addr; ++ u32 raf_next_len; ++ ++ /* Interrupts */ ++ volatile u32 *qspi_intr; ++ volatile struct bcm_idm_qspi_ctrl *idm_qspi; ++ ++ /* current flex mode settings */ ++ struct bcm_flex_mode flex_mode; ++}; ++ ++static void bcmspi_enable_interrupt(struct bcmspi_priv *priv, u32 mask) ++{ ++ priv->idm_qspi->io_ctrl_direct |= cpu_to_le32(mask << 2); ++} ++ ++static void bcmspi_disable_interrupt(struct bcmspi_priv *priv, u32 mask) ++{ ++ priv->idm_qspi->io_ctrl_direct &= cpu_to_le32(~(mask << 2)); ++} ++ ++static void bcmspi_clear_interrupt(struct bcmspi_priv *priv, u32 mask) ++{ ++ int i; ++ ++ for(i=0; iqspi_intr[i] = cpu_to_le32(1); ++ } ++ } ++} ++ ++static u32 bcmspi_read_interrupt(struct bcmspi_priv *priv) ++{ ++ int i; ++ u32 status = 0; ++ ++ for(i=0; iqspi_intr[i] & cpu_to_le32(1)) { ++ status |= 1UL << i; ++ } ++ } ++ ++ return status; ++} ++ ++static void bcmspi_flush_prefetch_buffers(struct bcmspi_priv *priv) ++{ ++ priv->bspi_hw->b0_ctrl = 0; ++ priv->bspi_hw->b1_ctrl = 0; ++ priv->bspi_hw->b0_ctrl = cpu_to_le32(1); ++ priv->bspi_hw->b1_ctrl = cpu_to_le32(1); ++} ++ ++static int bcmspi_lr_is_fifo_empty(struct bcmspi_priv *priv) ++{ ++ return priv->bspi_hw_raf->status & cpu_to_le32(QSPI_BSPI_RAF_STATUS_FIFO_EMPTY_MASK); ++} ++ ++static inline u32 bcmspi_lr_read_fifo(struct bcmspi_priv *priv) ++{ ++ /* for performance reasons return the raw data, rather than ++ * byte-swapped data. This works because the caller writes ++ * values 32-bits at a time to the destination buffer, giving ++ * an automatic byte-swap on big-endian machines. */ ++ ++ return priv->bspi_hw_raf->read_data; ++} ++ ++static inline void bcmspi_lr_start(struct bcmspi_priv *priv) ++{ ++ priv->bspi_hw_raf->ctrl = cpu_to_le32(QSPI_BSPI_RAF_CONTROL_START_MASK); ++} ++ ++static inline void bcmspi_lr_clear(struct bcmspi_priv *priv) ++{ ++ priv->bspi_hw_raf->ctrl = cpu_to_le32(QSPI_BSPI_RAF_CONTROL_CLEAR_MASK); ++ bcmspi_flush_prefetch_buffers(priv); ++} ++ ++static inline int bcmspi_is_4_byte_mode(struct bcmspi_priv *priv) ++{ ++ return priv->flex_mode.addrlen == BSPI_ADDRLEN_4BYTES; ++} ++ ++static int bcmbspi_flash_type(struct bcmspi_priv *priv); ++ ++static int bcmspi_set_flex_mode(struct bcmspi_priv *priv, ++ int width, int addrlen, int hp) ++{ ++ int bpc = 0, bpp = dummy_cycles, command = read_opcode; ++ int flex_mode = 1, error = 0; ++ ++ switch (width) { ++ case BSPI_WIDTH_1BIT: ++ if (addrlen == BSPI_ADDRLEN_3BYTES) { ++ /* default mode, does not need flex_cmd */ ++ flex_mode = 0; ++ } else { ++ bpp = 8; /* dummy cycles */ ++ //if (bcmbspi_flash_type(priv) == BSPI_FLASH_TYPE_SPANSION) ++ // command = OPCODE_FAST_READ_4B; ++ //else ++ command = OPCODE_FAST_READ; ++ } ++ break; ++ case BSPI_WIDTH_2BIT: ++ bpc = 0x00000001; /* only data is 2-bit */ ++ if (addr_multi) { ++ bpc |= 0x00010000; ++ } ++ if (hp) { ++ bpc |= 0x00010100; /* address and mode are 2-bit too */ ++ bpp |= QSPI_BSPI_BPP_MODE_BPP_MASK; ++ } ++ break; ++ case BSPI_WIDTH_4BIT: ++ bpc = 0x00000002; /* only data is 4-bit */ ++ if (addr_multi) { ++ bpc |= 0x00020000; ++ } ++ if (hp) { ++ bpc |= 0x00020200; /* address and mode are 4-bit too */ ++ bpp |= QSPI_BSPI_BPP_MODE_BPP_MASK; ++ } ++ break; ++ default: ++ error = 1; ++ break; ++ } ++ ++ if (addrlen == BSPI_ADDRLEN_4BYTES) { ++ bpp |= QSPI_BSPI_BPP_ADDR_BPP_SELECT_MASK; ++ } ++ ++ if (!error) { ++ priv->bspi_hw->flex_mode_enable = 0; ++ priv->bspi_hw->bits_per_cycle = cpu_to_le32(bpc); ++ priv->bspi_hw->bits_per_phase = cpu_to_le32(bpp); ++ priv->bspi_hw->cmd_and_mode_byte = cpu_to_le32(command); ++ priv->bspi_hw->flex_mode_enable = flex_mode ? ++ cpu_to_le32(QSPI_BSPI_FLEX_MODE_ENABLE_MASK) ++ : 0; ++ DBG("%s: width=%d addrlen=%d hp=%d\n", ++ __func__, width, addrlen, hp); ++ DBG("%s: fme=%08x bpc=%08x bpp=%08x cmd=%08x\n", __func__, ++ le32_to_cpu(priv->bspi_hw->flex_mode_enable), ++ le32_to_cpu(priv->bspi_hw->bits_per_cycle), ++ le32_to_cpu(priv->bspi_hw->bits_per_phase), ++ le32_to_cpu(priv->bspi_hw->cmd_and_mode_byte)); ++ } ++ ++ return error; ++} ++ ++static void bcmspi_set_mode(struct bcmspi_priv *priv, ++ int width, int addrlen, int hp) ++{ ++ int error = 0; ++ int show_info = 0; ++ ++ if ((width != -1 && width != priv->flex_mode.width) || ++ (hp != -1 && hp != priv->flex_mode.hp)) { ++ /* Don't print things if only for address mode change because it ++ * could be very frequent. */ ++ show_info = 1; ++ } ++ if (width == -1) ++ width = priv->flex_mode.width; ++ if (addrlen == -1) ++ addrlen = priv->flex_mode.addrlen; ++ if (hp == -1) ++ hp = priv->flex_mode.hp; ++ ++ error = bcmspi_set_flex_mode(priv, width, addrlen, hp); ++ ++ if (!error) { ++ priv->flex_mode.width = width; ++ priv->flex_mode.addrlen = addrlen; ++ priv->flex_mode.hp = hp; ++ if (show_info) { ++ dev_info(&priv->pdev->dev, ++ "%d-lane output, %d-byte address%s\n", ++ priv->flex_mode.width, ++ priv->flex_mode.addrlen, ++ priv->flex_mode.hp ? ", high-performance mode" : ""); ++ } ++ } else ++ dev_warn(&priv->pdev->dev, ++ "INVALID COMBINATION: width=%d addrlen=%d hp=%d\n", ++ width, addrlen, hp); ++} ++ ++static void bcmspi_set_chip_select(struct bcmspi_priv *priv, int cs) ++{ ++ if (priv->curr_cs != cs) { ++ DBG("Switching CS%1d => CS%1d\n", ++ priv->curr_cs, cs); ++ ++ /* We don't have multiple chip selects for now */ ++ } ++ priv->curr_cs = cs; ++ ++} ++ ++static inline int is_bspi_chip_select(struct bcmspi_priv *priv, u8 cs) ++{ ++ return priv->bspi_chip_select & (1 << cs); ++} ++ ++static void bcmspi_disable_bspi(struct bcmspi_priv *priv) ++{ ++ int i; ++ ++ if (!priv->bspi_hw || !priv->bspi_enabled) ++ return; ++ if ((priv->bspi_hw->mast_n_boot_ctrl & cpu_to_le32(1)) == 1) { ++ priv->bspi_enabled = 0; ++ return; ++ } ++ ++ DBG("disabling bspi\n"); ++ for (i = 0; i < 1000; i++) { ++ if ((priv->bspi_hw->busy_status & cpu_to_le32(1)) == 0) { ++ priv->bspi_hw->mast_n_boot_ctrl = cpu_to_le32(1); ++ priv->bspi_enabled = 0; ++ udelay(1); ++ return; ++ } ++ udelay(1); ++ } ++ dev_warn(&priv->pdev->dev, "timeout setting MSPI mode\n"); ++} ++ ++static void bcmspi_enable_bspi(struct bcmspi_priv *priv) ++{ ++ if (!priv->bspi_hw || priv->bspi_enabled) ++ return; ++ if ((priv->bspi_hw->mast_n_boot_ctrl & cpu_to_le32(1)) == 0) { ++ priv->bspi_enabled = 1; ++ return; ++ } ++ ++ DBG("enabling bspi\n"); ++ priv->bspi_hw->mast_n_boot_ctrl = 0; ++ priv->bspi_enabled = 1; ++} ++ ++static void bcmspi_hw_set_parms(struct bcmspi_priv *priv, ++ const struct bcmspi_parms *xp) ++{ ++ if (xp->speed_hz) { ++ unsigned int spbr = priv->mspi_refclk / (2 * xp->speed_hz); ++ ++ priv->mspi_hw->spcr0_lsb = cpu_to_le32(max(min(spbr, SPBR_MAX), SPBR_MIN)); ++ } else { ++ priv->mspi_hw->spcr0_lsb = cpu_to_le32(SPBR_MIN); ++ } ++ ++ if (priv->pos.msg == NULL || xp->bits_per_word > 8) { ++ /* Global hw init for 16bit spi_transfer */ ++ int bits = xp->bits_per_word; ++ bits = bits? (bits == 16? 0 : bits) : 8; ++ priv->mspi_hw->spcr0_msb = cpu_to_le32(0x80 | /* Master */ ++ (bits << 2) | ++ (xp->mode & 3)); ++ } else { ++ /* Configure for a new 8-bit spi_transfer */ ++ if (priv->pos.byte == 0) { ++ /* Use 16-bit MSPI transfer for performance if applicable */ ++ if (priv->pos.mspi_16bit ^ (!(priv->pos.trans->len & 1))) { ++ /* Update it only if needed */ ++ priv->pos.mspi_16bit = !priv->pos.mspi_16bit; ++ priv->mspi_hw->spcr0_msb = cpu_to_le32(0x80 | /* Master */ ++ ((priv->pos.mspi_16bit? 0 : 8) << 2) | ++ (xp->mode & 3)); ++ } ++ } ++ } ++ priv->last_parms = *xp; ++} ++ ++#define PARMS_NO_OVERRIDE 0 ++#define PARMS_OVERRIDE 1 ++ ++static int bcmspi_update_parms(struct bcmspi_priv *priv, ++ struct spi_device *spidev, struct spi_transfer *trans, int override) ++{ ++ struct bcmspi_parms xp; ++ ++ xp.speed_hz = min(trans->speed_hz ? trans->speed_hz : ++ (spidev->max_speed_hz ? spidev->max_speed_hz : DEFAULT_SPEED_HZ), ++ DEFAULT_SPEED_HZ); ++ xp.chip_select = spidev->chip_select; ++ xp.mode = spidev->mode; ++ xp.bits_per_word = trans->bits_per_word ? trans->bits_per_word : ++ (spidev->bits_per_word ? spidev->bits_per_word : 8); ++ ++ if ((override == PARMS_OVERRIDE) || ++ ((xp.speed_hz == priv->last_parms.speed_hz) && ++ (xp.chip_select == priv->last_parms.chip_select) && ++ (xp.mode == priv->last_parms.mode) && ++ (xp.bits_per_word == priv->last_parms.bits_per_word))) { ++ bcmspi_hw_set_parms(priv, &xp); ++ return 0; ++ } ++ /* no override, and parms do not match */ ++ return 1; ++} ++ ++ ++static int bcmspi_setup(struct spi_device *spi) ++{ ++ struct bcmspi_parms *xp; ++ struct bcmspi_priv *priv = spi_master_get_devdata(spi->master); ++ unsigned int speed_hz; ++ ++ DBG("%s\n", __func__); ++ ++ if (spi->bits_per_word > 16) ++ return -EINVAL; ++ ++ /* Module parameter override */ ++ if (max_hz != 0) { ++ speed_hz = max_hz; ++ } else { ++ speed_hz = spi->max_speed_hz; ++ } ++ ++ xp = spi_get_ctldata(spi); ++ if (!xp) { ++ xp = kzalloc(sizeof(struct bcmspi_parms), GFP_KERNEL); ++ if (!xp) ++ return -ENOMEM; ++ spi_set_ctldata(spi, xp); ++ } ++ if (speed_hz < priv->max_speed_hz) ++ xp->speed_hz = speed_hz; ++ else ++ xp->speed_hz = 0; ++ ++ priv->cru_hw->cru_control &= cpu_to_le32(~0x00000006); ++ (void)priv->cru_hw->cru_control; /* Need to read back */ ++ if (speed_hz >= 62500000) { ++ priv->cru_hw->cru_control |= cpu_to_le32(0x00000006); ++ } else if (speed_hz >= 50000000) { ++ priv->cru_hw->cru_control |= cpu_to_le32(0x00000002); ++ } else if (speed_hz >= 31250000) { ++ priv->cru_hw->cru_control |= cpu_to_le32(0x00000004); ++ } ++ (void)priv->cru_hw->cru_control; /* Need to read back */ ++ ++ xp->chip_select = spi->chip_select; ++ xp->mode = spi->mode; ++ xp->bits_per_word = spi->bits_per_word ? spi->bits_per_word : 8; ++ ++ return 0; ++} ++ ++/* stop at end of transfer, no other reason */ ++#define FNB_BREAK_NONE 0 ++/* stop at end of spi_message */ ++#define FNB_BREAK_EOM 1 ++/* stop at end of spi_transfer if delay */ ++#define FNB_BREAK_DELAY 2 ++/* stop at end of spi_transfer if cs_change */ ++#define FNB_BREAK_CS_CHANGE 4 ++/* stop if we run out of bytes */ ++#define FNB_BREAK_NO_BYTES 8 ++/* stop at end of spi_transfer */ ++#define FNB_BREAK_EOT 16 ++ ++/* events that make us stop filling TX slots */ ++#define FNB_BREAK_TX (FNB_BREAK_EOM | FNB_BREAK_DELAY | \ ++ FNB_BREAK_CS_CHANGE) ++ ++/* events that make us deassert CS */ ++#define FNB_BREAK_DESELECT (FNB_BREAK_EOM | FNB_BREAK_CS_CHANGE) ++ ++ ++static int find_next_byte(struct bcmspi_priv *priv, struct position *p, ++ struct list_head *completed, int flags) ++{ ++ int ret = FNB_BREAK_NONE; ++ ++ p->byte++; ++ ++ while (p->byte >= p->trans->len) { ++ /* we're at the end of the spi_transfer */ ++ ++ /* in TX mode, need to pause for a delay or CS change */ ++ if (p->trans->delay_usecs && (flags & FNB_BREAK_DELAY)) ++ ret |= FNB_BREAK_DELAY; ++ if (p->trans->cs_change && (flags & FNB_BREAK_CS_CHANGE)) ++ ret |= FNB_BREAK_CS_CHANGE; ++ if (ret) ++ return ret; ++ ++ /* advance to next spi_message? */ ++ if (list_is_last(&p->trans->transfer_list, ++ &p->msg->transfers)) { ++ struct spi_message *next_msg = NULL; ++ ++ /* TX breaks at the end of each message as well */ ++ if (!completed || (flags & FNB_BREAK_EOM)) { ++ DBG("find_next_byte: advance msg exit\n"); ++ return FNB_BREAK_EOM; ++ } ++ if (!list_is_last(&p->msg->queue, &priv->msg_queue)) { ++ next_msg = list_entry(p->msg->queue.next, ++ struct spi_message, queue); ++ } ++ /* delete from run queue, add to completion queue */ ++ list_del(&p->msg->queue); ++ list_add_tail(&p->msg->queue, completed); ++ ++ p->msg = next_msg; ++ p->byte = 0; ++ if (p->msg == NULL) { ++ p->trans = NULL; ++ ret = FNB_BREAK_NO_BYTES; ++ break; ++ } ++ ++ /* ++ * move on to the first spi_transfer of the new ++ * spi_message ++ */ ++ p->trans = list_entry(p->msg->transfers.next, ++ struct spi_transfer, transfer_list); ++ } else { ++ /* or just advance to the next spi_transfer */ ++ p->trans = list_entry(p->trans->transfer_list.next, ++ struct spi_transfer, transfer_list); ++ p->byte = 0; ++ ++ /* Separate spi_transfers into MSPI transfers */ ++ ret = FNB_BREAK_EOT; ++ } ++ } ++ DBG("find_next_byte: msg %p trans %p len %d byte %d ret %x\n", ++ p->msg, p->trans, p->trans ? p->trans->len : 0, p->byte, ret); ++ return ret; ++} ++ ++static void read_from_hw(struct bcmspi_priv *priv, struct list_head *completed) ++{ ++ struct position p; ++ int slot = 0, n = priv->outstanding_bytes; ++ ++ DBG("%s\n", __func__); ++ ++ p = priv->pos; ++ ++ while (n > 0) { ++ BUG_ON(p.msg == NULL); ++ ++ if (p.trans->bits_per_word <= 8) { ++ u8 *buf = p.trans->rx_buf; ++ ++ if (buf) { ++ ++ if (p.mspi_16bit) { ++ /* Using 16-bit SPI transfers for performance */ ++ buf[p.byte] = ++ le32_to_cpu(priv->mspi_hw->rxram[(slot << 1) + 0]) & 0xff; ++ DBG("RD %02x\n", buf ? buf[p.byte] : 0xff); ++ buf[p.byte + 1] = ++ le32_to_cpu(priv->mspi_hw->rxram[(slot << 1) + 1]) & 0xff; ++ DBG("RD %02x\n", buf ? buf[p.byte + 1] : 0xff); ++ } else { ++ buf[p.byte] = ++ le32_to_cpu(priv->mspi_hw->rxram[(slot << 1) + 1]) & 0xff; ++ DBG("RD %02x\n", buf ? buf[p.byte] : 0xff); ++ } ++ } ++ } else { ++ u16 *buf = p.trans->rx_buf; ++ ++ if (buf) { ++ buf[p.byte] = ++ ((le32_to_cpu(priv->mspi_hw->rxram[(slot << 1) + 1]) & 0xff) << 0) | ++ ((le32_to_cpu(priv->mspi_hw->rxram[(slot << 1) + 0] & 0xff)) << 8); ++ DBG("RD %04x\n", buf ? buf[p.byte] : 0xffff); ++ } ++ } ++ slot++; ++ n--; ++ p.msg->actual_length++; ++ if (p.mspi_16bit) { ++ p.byte++; ++ p.msg->actual_length++; ++ } ++ ++ find_next_byte(priv, &p, completed, FNB_BREAK_NONE); ++ } ++ ++ priv->pos = p; ++ priv->outstanding_bytes = 0; ++} ++ ++static void write_to_hw(struct bcmspi_priv *priv) ++{ ++ struct position p; ++ int slot = 0, fnb = 0; ++ struct spi_message *msg = NULL; ++ ++ DBG("%s\n", __func__); ++ ++ bcmspi_disable_bspi(priv); ++ ++ p = priv->pos; ++ ++ while (1) { ++ if (p.msg == NULL) ++ break; ++ if (!msg) { ++ msg = p.msg; ++ bcmspi_update_parms(priv, msg->spi, p.trans, ++ PARMS_OVERRIDE); ++ } else { ++ /* break if the speed, bits, etc. changed */ ++ if (bcmspi_update_parms(priv, msg->spi, p.trans, ++ PARMS_NO_OVERRIDE)) { ++ DBG("parms don't match, breaking\n"); ++ break; ++ } ++ } ++ if (p.trans->bits_per_word <= 8) { ++ const u8 *buf = p.trans->tx_buf; ++ ++ priv->mspi_hw->txram[slot << 1] = ++ cpu_to_le32(buf ? (buf[p.byte] & 0xff) : 0xff); ++ DBG("WR %02x\n", buf ? buf[p.byte] : 0xff); ++ ++ if (priv->pos.mspi_16bit) { ++ /* Using 16-bit SPI transfers for performance */ ++ p.byte++; ++ priv->mspi_hw->txram[(slot << 1) + 1] = ++ cpu_to_le32(buf ? (buf[p.byte] & 0xff) : 0xff); ++ DBG("WR %02x\n", buf ? buf[p.byte] : 0xff); ++ priv->mspi_hw->cdram[slot] = cpu_to_le32(0xce); ++ } else { ++ priv->mspi_hw->cdram[slot] = cpu_to_le32(0x8e); ++ } ++ ++ } else { ++ const u16 *buf = p.trans->tx_buf; ++ ++ priv->mspi_hw->txram[(slot << 1) + 0] = ++ cpu_to_le32(buf ? (buf[p.byte] >> 8) : 0xff); ++ priv->mspi_hw->txram[(slot << 1) + 1] = ++ cpu_to_le32(buf ? (buf[p.byte] & 0xff) : 0xff); ++ DBG("WR %04x\n", buf ? buf[p.byte] : 0xffff); ++ priv->mspi_hw->cdram[slot] = cpu_to_le32(0xce); ++ } ++ slot++; ++ ++ fnb = find_next_byte(priv, &p, NULL, FNB_BREAK_TX); ++ ++ if (fnb & FNB_BREAK_CS_CHANGE) ++ priv->cs_change = 1; ++ if (fnb & FNB_BREAK_DELAY) ++ priv->next_udelay = p.trans->delay_usecs; ++ if (fnb || (slot == NUM_CDRAM)) ++ break; ++ } ++ ++ if (slot) { ++ DBG("submitting %d slots\n", slot); ++ priv->mspi_hw->newqp = 0; ++ priv->mspi_hw->endqp = cpu_to_le32(slot - 1); ++ ++ /* deassert CS on the final byte */ ++ if (fnb & FNB_BREAK_DESELECT) ++ priv->mspi_hw->cdram[slot - 1] &= cpu_to_le32(~0x80); ++ ++ /* tell HIF_MSPI which CS to use */ ++ bcmspi_set_chip_select(priv, msg->spi->chip_select); ++ ++ priv->mspi_hw->write_lock = cpu_to_le32(1); ++ priv->mspi_hw->spcr2 = cpu_to_le32(0xe0); /* cont | spe | spifie */ ++ ++ priv->state = STATE_RUNNING; ++ priv->outstanding_bytes = slot; ++ } else { ++ priv->mspi_hw->write_lock = 0; ++ priv->state = STATE_IDLE; ++ } ++} ++ ++#define DWORD_ALIGNED(a) (!(((unsigned long)(a)) & 3)) ++#define ACROSS_16MB(a, l) (((a) ^ ((a) + (l) - 1)) & 0xFF000000) ++ ++static int bcmspi_emulate_flash_read(struct bcmspi_priv *priv, ++ struct spi_message *msg) ++{ ++ u32 addr, len; ++ int idx = 0; /* Also used for checking continuation */ ++ unsigned long flags = 0; ++ ++ /* Check if it's a continuation */ ++ if (priv->raf_next_len != 0) { ++ ++ /* Continuation (read across 16MB boundary) */ ++ addr = priv->raf_next_addr; ++ len = priv->raf_next_len; ++ ++ /* Update upper address byte */ ++ if (bcmspi_is_4_byte_mode(priv)) { ++ priv->bspi_hw->flash_upper_addr_byte = cpu_to_le32(addr & 0xFF000000); ++ /* Flush prefecth buffers since upper byte changed */ ++ bcmspi_flush_prefetch_buffers(priv); ++ } ++ ++ } else { ++ ++ /* It's the first session of this transfer */ ++ struct spi_transfer *trans; ++ u8 *buf; ++ ++ /* acquire lock when the MSPI is idle */ ++ while (1) { ++ spin_lock_irqsave(&priv->lock, flags); ++ if (priv->state == STATE_IDLE) ++ break; ++ spin_unlock_irqrestore(&priv->lock, flags); ++ if (priv->state == STATE_SHUTDOWN) ++ return -EIO; ++ udelay(1); ++ } ++ bcmspi_set_chip_select(priv, msg->spi->chip_select); ++ ++ /* first transfer - OPCODE_READ + 3-byte address */ ++ trans = list_entry(msg->transfers.next, struct spi_transfer, ++ transfer_list); ++ buf = (void *)trans->tx_buf; ++ ++ idx = 1; ++ ++ /* Check upper address byte for 4-byte mode */ ++ if (bcmspi_is_4_byte_mode(priv)) { ++ addr = buf[idx++] << 24; ++ } else { ++ addr = 0; ++ } ++ ++ /* ++ * addr coming into this function is a raw flash offset ++ * we need to convert it to the BSPI address ++ */ ++ addr |= (buf[idx] << 16) | (buf[idx+1] << 8) | buf[idx+2]; ++ ++ /* second transfer - read result into buffer */ ++ trans = list_entry(msg->transfers.next->next, struct spi_transfer, ++ transfer_list); ++ ++ buf = (void *)trans->rx_buf; ++ ++ len = trans->len; ++ ++ /* non-aligned and very short transfers are handled by MSPI */ ++ if (unlikely(!DWORD_ALIGNED(addr) || ++ !DWORD_ALIGNED(buf) || ++ len < sizeof(u32) || ++ !priv->bspi_hw_raf)) { ++ spin_unlock_irqrestore(&priv->lock, flags); ++ return -1; ++ } ++ ++ /* Flush prefetch buffers only if upper address byte changed */ ++ if ((addr & 0xFF000000) != le32_to_cpu(priv->bspi_hw->flash_upper_addr_byte)) { ++ bcmspi_flush_prefetch_buffers(priv); ++ /* Update upper address byte */ ++ priv->bspi_hw->flash_upper_addr_byte = cpu_to_le32(addr & 0xFF000000); ++ } ++ ++ /* Switching to BSPI */ ++ bcmspi_enable_bspi(priv); ++ ++ DBG("%s: dst %p src %p len %x addr BSPI %06x\n", ++ __func__, buf, addr, len, addr); ++ ++ /* initialize software parameters */ ++ priv->xfer_status = 0; ++ priv->cur_xfer = trans; ++ priv->cur_xfer_idx = 0; ++ priv->cur_msg = msg; ++ priv->actual_length = idx + 4 + trans->len; ++ } ++ ++ if (bcmspi_is_4_byte_mode(priv) && ACROSS_16MB(addr, len)) { ++ ++ /* Size for the first session */ ++ u32 bytes = 0x1000000 - (addr & 0x00FFFFFF); ++ ++ /* Address and size for remaining sessions */ ++ priv->raf_next_addr = addr + bytes; ++ priv->raf_next_len = len - bytes; ++ ++ len = bytes; ++ ++ } else { ++ priv->raf_next_len = 0; ++ } ++ ++ /* Length for this session */ ++ priv->cur_xfer_len = len; ++ ++ /* setup hardware */ ++ /* address must be 4-byte aligned */ ++ priv->bspi_hw_raf->start_address = cpu_to_le32(addr & 0x00FFFFFF); ++ priv->bspi_hw_raf->num_words = cpu_to_le32((len + 3) >> 2); ++ priv->bspi_hw_raf->watermark = 0; ++ ++ DBG("READ: %08x %08x (%08x)\n", addr, ((len + 3) >> 2), len); ++ ++ bcmspi_clear_interrupt(priv, 0xffffffff); ++ bcmspi_enable_interrupt(priv, BSPI_LR_INTERRUPTS_ALL); ++ bcmspi_lr_start(priv); ++ ++ if (idx) { ++ spin_unlock_irqrestore(&priv->lock, flags); ++ } ++ ++ return 0; ++} ++ ++/* ++ * m25p80_read() calls wait_till_ready() before each read to check ++ * the flash status register for pending writes. ++ * ++ * This can be safely skipped if our last transaction was just an ++ * emulated BSPI read. ++ */ ++static int bcmspi_emulate_flash_rdsr(struct bcmspi_priv *priv, ++ struct spi_message *msg) ++{ ++ u8 *buf; ++ struct spi_transfer *trans; ++ ++ if (priv->bspi_enabled == 0) ++ return 1; ++ ++ trans = list_entry(msg->transfers.next->next, struct spi_transfer, ++ transfer_list); ++ ++ buf = (void *)trans->rx_buf; ++ *buf = 0x00; ++ ++ msg->actual_length = 2; ++ msg->status = 0; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) ++ spi_finalize_current_message(priv->master); ++#else ++ msg->complete(msg->context); ++#endif ++ ++ return 0; ++} ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) ++static int bcmspi_prepare_transfer(struct spi_master *master) ++{ ++ return 0; ++} ++ ++static int bcmspi_unprepare_transfer(struct spi_master *master) ++{ ++ return 0; ++} ++#endif ++ ++static int bcmspi_transfer_one(struct spi_master *master, struct spi_message *msg) ++{ ++ struct bcmspi_priv *priv = spi_master_get_devdata(master); ++ unsigned long flags; ++ ++ DBG("%s\n", __func__); ++ ++ if (is_bspi_chip_select(priv, msg->spi->chip_select)) { ++ struct spi_transfer *trans; ++ ++ trans = list_entry(msg->transfers.next, ++ struct spi_transfer, transfer_list); ++ if (trans && trans->len && trans->tx_buf) { ++ u8 command = ((u8 *)trans->tx_buf)[0]; ++ switch (command) { ++ case OPCODE_FAST_READ: ++ if (bcmspi_emulate_flash_read(priv, msg) == 0) ++ return 0; ++ break; ++ case OPCODE_RDSR: ++ if (bcmspi_emulate_flash_rdsr(priv, msg) == 0) ++ return 0; ++ break; ++ case OPCODE_EN4B: ++ DBG("ENABLE 4-BYTE MODE\n"); ++ bcmspi_set_mode(priv, -1, BSPI_ADDRLEN_4BYTES, -1); ++ break; ++ case OPCODE_EX4B: ++ DBG("DISABLE 4-BYTE MODE\n"); ++ bcmspi_set_mode(priv, -1, BSPI_ADDRLEN_3BYTES, -1); ++ break; ++ case OPCODE_BRWR: ++ { ++ u8 enable = ((u8 *)trans->tx_buf)[1]; ++ DBG("%s 4-BYTE MODE\n", enable ? "ENABLE" : "DISABLE"); ++ bcmspi_set_mode(priv, -1, ++ enable ? BSPI_ADDRLEN_4BYTES : ++ BSPI_ADDRLEN_3BYTES, -1); ++ } ++ break; ++ default: ++ break; ++ } ++ ++ /* Mark prefetch buffers dirty (by using upper byte) if needed */ ++ switch(command) { ++ case OPCODE_RDID: ++ case OPCODE_WREN: ++ case OPCODE_WRDI: ++ case OPCODE_RCR: ++ case OPCODE_READ: ++ case OPCODE_RDSR: ++ case OPCODE_WRSR: ++ case OPCODE_RDFSR: ++ case OPCODE_FAST_READ: ++ case OPCODE_FAST_READ_4B: ++ case OPCODE_EN4B: ++ case OPCODE_EX4B: ++ case OPCODE_BRWR: ++ /* These are known opcodes that are not writing/erasing */ ++ break; ++ default: ++ /* Could be writing/erasing; mark buffers dirty */ ++ priv->bspi_hw->flash_upper_addr_byte = cpu_to_le32(0xff000000); ++ break; ++ } ++ } ++ } ++ ++ spin_lock_irqsave(&priv->lock, flags); ++ ++ if (priv->state == STATE_SHUTDOWN) { ++ spin_unlock_irqrestore(&priv->lock, flags); ++ return -EIO; ++ } ++ ++ msg->actual_length = 0; ++ ++ list_add_tail(&msg->queue, &priv->msg_queue); ++ ++ if (priv->state == STATE_IDLE) { ++ BUG_ON(priv->pos.msg != NULL); ++ priv->pos.msg = msg; ++ priv->pos.trans = list_entry(msg->transfers.next, ++ struct spi_transfer, transfer_list); ++ priv->pos.byte = 0; ++ ++ write_to_hw(priv); ++ } ++ spin_unlock_irqrestore(&priv->lock, flags); ++ ++ return 0; ++} ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0) ++static int bcmspi_transfer(struct spi_device *spi, struct spi_message *msg) ++{ ++ return bcmspi_transfer_one(spi->master, msg); ++} ++#endif ++ ++static void bcmspi_cleanup(struct spi_device *spi) ++{ ++ struct bcmspi_parms *xp = spi_get_ctldata(spi); ++ ++ DBG("%s\n", __func__); ++ ++ kfree(xp); ++} ++ ++static irqreturn_t bcmspi_interrupt(int irq, void *dev_id) ++{ ++ struct bcmspi_priv *priv = dev_id; ++ ++ if (priv->bspi_enabled && priv->cur_xfer) { ++ int done = 0; ++ u32 status = bcmspi_read_interrupt(priv); ++ u32 *buf = (u32 *)priv->cur_xfer->rx_buf; ++ if (status & BSPI_LR_INTERRUPTS_DATA) { ++ while (!bcmspi_lr_is_fifo_empty(priv)) { ++ u32 data = bcmspi_lr_read_fifo(priv); ++ if (likely(priv->cur_xfer_len >= 4)) { ++ buf[priv->cur_xfer_idx++] = data; ++ priv->cur_xfer_len -= 4; ++ } else { ++ /* ++ * Read out remaining bytes, make sure ++ * we do not cross the buffer boundary ++ */ ++ u8 *cbuf = ++ (u8 *)&buf[priv->cur_xfer_idx]; ++ data = cpu_to_le32(data); ++ while (priv->cur_xfer_len) { ++ *cbuf++ = (u8)data; ++ data >>= 8; ++ priv->cur_xfer_len--; ++ } ++ } ++ } ++ } ++ if (status & BSPI_LR_INTERRUPTS_ERROR) { ++ dev_err(&priv->pdev->dev, "ERROR %02x\n", status); ++ priv->xfer_status = -EIO; ++ } else if ((status & QSPI_INTR_BSPI_LR_SESSION_DONE_MASK) && ++ priv->cur_xfer_len == 0) { ++ ++ if (priv->raf_next_len) { ++ ++ /* Continuation for reading across 16MB boundary */ ++ bcmspi_disable_interrupt(priv, BSPI_LR_INTERRUPTS_ALL); ++ bcmspi_emulate_flash_read(priv, NULL); ++ return IRQ_HANDLED; ++ ++ } else { ++ done = 1; ++ } ++ } ++ ++ if (done) { ++ priv->cur_xfer = NULL; ++ bcmspi_disable_interrupt(priv, BSPI_LR_INTERRUPTS_ALL); ++ ++ if (priv->xfer_status) { ++ bcmspi_lr_clear(priv); ++ } else { ++ if (priv->cur_msg) { ++ priv->cur_msg->actual_length = priv->actual_length; ++ priv->cur_msg->status = 0; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) ++ spi_finalize_current_message(priv->master); ++#else ++ priv->cur_msg->complete(priv->cur_msg->context); ++#endif ++ } ++ } ++ priv->cur_msg = NULL; ++ } ++ bcmspi_clear_interrupt(priv, status); ++ return IRQ_HANDLED; ++ } ++ ++ if (priv->mspi_hw->mspi_status & cpu_to_le32(1)) { ++ /* clear interrupt */ ++ priv->mspi_hw->mspi_status &= cpu_to_le32(~1); ++ bcmspi_clear_interrupt(priv, QSPI_INTR_MSPI_DONE_MASK); ++ ++ tasklet_schedule(&priv->tasklet); ++ return IRQ_HANDLED; ++ } else ++ return IRQ_NONE; ++} ++ ++static void bcmspi_complete(void *arg) ++{ ++ complete(arg); ++} ++ ++static void bcmspi_tasklet(unsigned long param) ++{ ++ struct bcmspi_priv *priv = (void *)param; ++ struct list_head completed; ++ struct spi_message *msg; ++ unsigned long flags; ++ ++ INIT_LIST_HEAD(&completed); ++ spin_lock_irqsave(&priv->lock, flags); ++ ++ if (priv->next_udelay) { ++ udelay(priv->next_udelay); ++ priv->next_udelay = 0; ++ } ++ ++ msg = priv->pos.msg; ++ ++ read_from_hw(priv, &completed); ++ if (priv->cs_change) { ++ udelay(10); ++ priv->cs_change = 0; ++ } ++ ++ write_to_hw(priv); ++ spin_unlock_irqrestore(&priv->lock, flags); ++ ++ while (!list_empty(&completed)) { ++ msg = list_first_entry(&completed, struct spi_message, queue); ++ list_del(&msg->queue); ++ msg->status = 0; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) ++ if (msg->complete == bcmspi_complete) ++ msg->complete(msg->context); ++ else ++ spi_finalize_current_message(priv->master); ++#else ++ if (msg->complete) ++ msg->complete(msg->context); ++#endif ++ ++ } ++} ++ ++static struct spi_master *default_master; ++ ++static int bcmspi_simple_transaction(struct bcmspi_parms *xp, ++ const void *tx_buf, int tx_len, void *rx_buf, int rx_len) ++{ ++ DECLARE_COMPLETION_ONSTACK(fini); ++ struct spi_message m; ++ struct spi_transfer t_tx, t_rx; ++ struct spi_device spi; ++ int ret; ++ ++ memset(&spi, 0, sizeof(spi)); ++ spi.max_speed_hz = xp->speed_hz; ++ spi.chip_select = xp->chip_select; ++ spi.mode = xp->mode; ++ spi.bits_per_word = xp->bits_per_word; ++ spi.master = default_master; ++ ++ spi_message_init(&m); ++ m.complete = bcmspi_complete; ++ m.context = &fini; ++ m.spi = &spi; ++ ++ memset(&t_tx, 0, sizeof(t_tx)); ++ memset(&t_rx, 0, sizeof(t_rx)); ++ t_tx.tx_buf = tx_buf; ++ t_tx.len = tx_len; ++ t_rx.rx_buf = rx_buf; ++ t_rx.len = rx_len; ++ ++ if (tx_len) ++ spi_message_add_tail(&t_tx, &m); ++ if (rx_len) ++ spi_message_add_tail(&t_rx, &m); ++ ++ ret = bcmspi_transfer_one(default_master, &m); ++ if (!ret) ++ wait_for_completion(&fini); ++ return ret; ++} ++ ++static void bcmspi_hw_init(struct bcmspi_priv *priv) ++{ ++ const struct bcmspi_parms bcmspi_default_parms_cs0 = { ++ .speed_hz = DEFAULT_SPEED_HZ, ++ .chip_select = 0, ++ .mode = SPI_MODE_3, ++ .bits_per_word = 8, ++ }; ++ ++ priv->mspi_hw->spcr1_lsb = 0; ++ priv->mspi_hw->spcr1_msb = 0; ++ priv->mspi_hw->newqp = 0; ++ priv->mspi_hw->endqp = 0; ++ priv->mspi_hw->spcr2 = cpu_to_le32(0x20); /* spifie */ ++ ++ bcmspi_hw_set_parms(priv, &bcmspi_default_parms_cs0); ++ ++ priv->bspi_enabled = 1; ++ bcmspi_disable_bspi(priv); ++} ++ ++static void bcmspi_hw_uninit(struct bcmspi_priv *priv) ++{ ++ priv->mspi_hw->spcr2 = 0x0; /* disable irq and enable bits */ ++ bcmspi_enable_bspi(priv); ++} ++ ++static int bcmbspi_flash_type(struct bcmspi_priv *priv) ++{ ++ char tx_buf[4]; ++ unsigned char jedec_id[5] = {0}; ++ int bspi_flash; ++ ++ /* Read ID */ ++ tx_buf[0] = OPCODE_RDID; ++ bcmspi_simple_transaction(&priv->last_parms, tx_buf, 1, &jedec_id, 5); ++ ++ switch (jedec_id[0]) { ++ case 0x01: /* Spansion */ ++ case 0xef: ++ bspi_flash = BSPI_FLASH_TYPE_SPANSION; ++ break; ++ case 0xc2: /* Macronix */ ++ bspi_flash = BSPI_FLASH_TYPE_MACRONIX; ++ break; ++ case 0xbf: /* SST */ ++ bspi_flash = BSPI_FLASH_TYPE_SST; ++ break; ++ case 0x89: /* Numonyx */ ++ bspi_flash = BSPI_FLASH_TYPE_NUMONYX; ++ break; ++ default: ++ bspi_flash = BSPI_FLASH_TYPE_UNKNOWN; ++ break; ++ } ++ return bspi_flash; ++} ++ ++static int bcmspi_set_quad_mode(struct bcmspi_priv *priv, int _enable) ++{ ++ char tx_buf[4]; ++ unsigned char cfg_reg, sts_reg; ++ ++ switch (bcmbspi_flash_type(priv)) { ++ case BSPI_FLASH_TYPE_SPANSION: ++ /* RCR */ ++ tx_buf[0] = OPCODE_RCR; ++ bcmspi_simple_transaction(&priv->last_parms, ++ tx_buf, 1, &cfg_reg, 1); ++ if (_enable) ++ cfg_reg |= 0x2; ++ else ++ cfg_reg &= ~0x2; ++ /* WREN */ ++ tx_buf[0] = OPCODE_WREN; ++ bcmspi_simple_transaction(&priv->last_parms, ++ tx_buf, 1, NULL, 0); ++ /* WRR */ ++ tx_buf[0] = OPCODE_WRR; ++ tx_buf[1] = 0; /* status register */ ++ tx_buf[2] = cfg_reg; /* configuration register */ ++ bcmspi_simple_transaction(&priv->last_parms, ++ tx_buf, 3, NULL, 0); ++ /* wait till ready */ ++ do { ++ tx_buf[0] = OPCODE_RDSR; ++ bcmspi_simple_transaction(&priv->last_parms, ++ tx_buf, 1, &sts_reg, 1); ++ udelay(1); ++ } while (sts_reg & 1); ++ break; ++ case BSPI_FLASH_TYPE_MACRONIX: ++ /* RDSR */ ++ tx_buf[0] = OPCODE_RDSR; ++ bcmspi_simple_transaction(&priv->last_parms, ++ tx_buf, 1, &cfg_reg, 1); ++ if (_enable) ++ cfg_reg |= 0x40; ++ else ++ cfg_reg &= ~0x40; ++ /* WREN */ ++ tx_buf[0] = OPCODE_WREN; ++ bcmspi_simple_transaction(&priv->last_parms, ++ tx_buf, 1, NULL, 0); ++ /* WRSR */ ++ tx_buf[0] = OPCODE_WRSR; ++ tx_buf[1] = cfg_reg; /* status register */ ++ bcmspi_simple_transaction(&priv->last_parms, ++ tx_buf, 2, NULL, 0); ++ /* wait till ready */ ++ do { ++ tx_buf[0] = OPCODE_RDSR; ++ bcmspi_simple_transaction(&priv->last_parms, ++ tx_buf, 1, &sts_reg, 1); ++ udelay(1); ++ } while (sts_reg & 1); ++ /* RDSR */ ++ tx_buf[0] = OPCODE_RDSR; ++ bcmspi_simple_transaction(&priv->last_parms, ++ tx_buf, 1, &cfg_reg, 1); ++ break; ++ case BSPI_FLASH_TYPE_SST: ++ case BSPI_FLASH_TYPE_NUMONYX: ++ /* TODO - send Quad mode control command */ ++ break; ++ default: ++ return _enable ? -1 : 0; ++ } ++ ++ return 0; ++} ++ ++static int bcmspi_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct brcmspi_platform_data *pdata; ++ struct bcmspi_priv *priv; ++ struct spi_master *master; ++ struct resource *res; ++ struct clk *clk; ++ int ret; ++ u32 irq; ++#ifdef CONFIG_OF ++ struct device_node *dn = pdev->dev.of_node; ++ u32 qspi_bus_id; ++ u32 qspi_cs; ++ int i, irqs_total; ++#endif ++ ++ DBG("bcmspi_probe\n"); ++ ++ pdata = (struct brcmspi_platform_data *)pdev->dev.platform_data; ++ ++ master = spi_alloc_master(dev, sizeof(struct bcmspi_priv)); ++ if (!master) { ++ dev_err(&pdev->dev, "error allocating spi_master\n"); ++ return -ENOMEM; ++ } ++ ++ priv = spi_master_get_devdata(master); ++ ++ priv->pdev = pdev; ++ priv->state = STATE_IDLE; ++ priv->pos.msg = NULL; ++ priv->pos.mspi_16bit = 0; ++ priv->master = master; ++ priv->raf_next_len = 0; ++ ++#ifndef CONFIG_OF ++ master->bus_num = pdev->id; ++#else ++ if (of_property_read_u32(dn, "#bus-id", &qspi_bus_id)) { ++ dev_warn(&pdev->dev, ++ "missing #bus-id property (default to 1)\n"); ++ qspi_bus_id = 1; ++ } ++ master->bus_num = qspi_bus_id; ++ pdev->id = qspi_bus_id; ++#endif ++ master->num_chipselect = 1; ++ master->mode_bits = SPI_MODE_3; ++ ++ master->setup = bcmspi_setup; ++ master->cleanup = bcmspi_cleanup; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) ++ master->prepare_transfer_hardware = bcmspi_prepare_transfer; ++ master->unprepare_transfer_hardware = bcmspi_unprepare_transfer; ++ master->transfer_one_message = bcmspi_transfer_one; ++ master->transfer = NULL; ++#else ++ master->transfer = bcmspi_transfer; ++#endif ++/* needed for supporting child SPI devices*/ ++#ifdef CONFIG_OF ++ master->dev.of_node = pdev->dev.of_node; ++#endif ++ ++ priv->mspi_hw = NULL; ++ priv->bspi_hw = NULL; ++ priv->bspi_hw_raf = NULL; ++ priv->qspi_intr = NULL; ++ priv->idm_qspi = NULL; ++ priv->irq = -1; ++ ++ /* Get MSPI reference clock and max speed hz */ ++#ifndef CONFIG_OF ++ clk = clk_get_sys(MSPI_REFCLK_SOURCE_DEVID, MSPI_REFCLK_SOURCE); ++#else ++ clk = of_clk_get (dn, 0); ++#endif /* CONFIG_OF */ ++ if (!clk) { ++ dev_err(&pdev->dev, "can't get reference clock frequency by %s\n", ++ MSPI_REFCLK_SOURCE); ++ ret = -EIO; ++ goto err2; ++ } ++ priv->mspi_refclk = (unsigned int)clk_get_rate(clk) * 2; ++ priv->max_speed_hz = priv->mspi_refclk / (2 * SPBR_MIN); ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!res) { ++ dev_err(&pdev->dev, "can't get resource 0\n"); ++ ret = -EIO; ++ goto err2; ++ } ++ /* MSPI register range */ ++ priv->mspi_hw = (volatile void *)ioremap(res->start, ++ res->end - res->start); ++ if (!priv->mspi_hw) { ++ dev_err(&pdev->dev, "can't ioremap\n"); ++ ret = -EIO; ++ goto err2; ++ } ++ DBG("priv->mspi_hw=%p\n", priv->mspi_hw); ++ ++ /* BSPI register range */ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); ++ if (res) { ++ priv->bspi_hw = (volatile void *)ioremap(res->start, ++ res->end - res->start); ++ if (!priv->bspi_hw) { ++ dev_err(&pdev->dev, "can't ioremap BSPI range\n"); ++ ret = -EIO; ++ goto err2; ++ } ++ } else ++ priv->bspi_hw = NULL; ++ DBG("priv->bspi_hw=%p\n", priv->bspi_hw); ++ ++ /* BSPI_RAF register range */ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 2); ++ if (res) { ++ priv->bspi_hw_raf = (volatile void *)ioremap(res->start, ++ res->end - res->start); ++ if (!priv->bspi_hw_raf) { ++ dev_err(&pdev->dev, "can't ioremap BSPI_RAF range\n"); ++ ret = -EIO; ++ goto err2; ++ } ++ } else ++ priv->bspi_hw_raf = NULL; ++ DBG("priv->bspi_hw_raf=%p\n", priv->bspi_hw_raf); ++ ++ /* QSPI interrupt register range */ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 3); ++ if (res) { ++ priv->qspi_intr = (volatile void *)ioremap(res->start, ++ res->end - res->start); ++ if (!priv->qspi_intr) { ++ dev_err(&pdev->dev, "can't ioremap QSPI interrupt range\n"); ++ ret = -EIO; ++ goto err2; ++ } ++ } else { ++ dev_err(&pdev->dev, "can't get resource 3\n"); ++ ret = -EIO; ++ goto err2; ++ } ++ DBG("priv->qspi_intr=%p\n", priv->qspi_intr); ++ ++ /* IDM QSPI io ctrl register range */ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 4); ++ if (res) { ++ priv->idm_qspi = (volatile void *)ioremap(res->start, ++ res->end - res->start); ++ if (!priv->idm_qspi) { ++ dev_err(&pdev->dev, "can't ioremap IDM QSPI range\n"); ++ ret = -EIO; ++ goto err2; ++ } ++ } else { ++ dev_err(&pdev->dev, "can't get resource 4\n"); ++ ret = -EIO; ++ goto err2; ++ } ++ DBG("priv->idm_qspi=%p\n", priv->idm_qspi); ++ ++ /* CRU control register */ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 5); ++ if (res) { ++ priv->cru_hw = (volatile void *)ioremap(res->start, ++ res->end - res->start); ++ if (!priv->cru_hw) { ++ dev_err(&pdev->dev, "can't ioremap CRU range\n"); ++ ret = -EIO; ++ goto err2; ++ } ++ } else { ++ dev_err(&pdev->dev, "can't get resource 4\n"); ++ ret = -EIO; ++ goto err2; ++ } ++ DBG("priv->cru_hw=%p\n", priv->cru_hw); ++ ++ /* IRQ */ ++#ifndef CONFIG_OF ++ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); ++ if (!res) { ++ dev_err(&pdev->dev, "no IRQ defined\n"); ++ ret = -ENODEV; ++ goto err2; ++ } ++#else ++ irqs_total = of_irq_count(dn); ++#endif /*CONFIG_OF*/ ++ ++ /* Basic initialization (before enabling interrupts) */ ++ priv->bspi_hw->mast_n_boot_ctrl = cpu_to_le32(1); ++ bcmspi_disable_interrupt(priv, 0xffffffff); ++ bcmspi_clear_interrupt(priv, 0xffffffff); ++ bcmspi_enable_interrupt(priv, QSPI_INTR_MSPI_DONE_MASK); ++ ++ /* Request all IRQs */ ++#ifndef CONFIG_OF ++ for(irq=(u32)res->start; irq<=(u32)res->end; irq++) { ++#else ++ for (i=0; idev, "unable to allocate IRQ\n"); ++ goto err1; ++ } ++ } ++ ++ bcmspi_hw_init(priv); ++ priv->curr_cs = -1; ++ ++#ifdef CONFIG_OF ++ if (of_property_read_u32(dn, "#chip-select", &qspi_cs)) { ++ dev_warn(&pdev->dev, ++ "missing #chip-selects property (default to 0)\n"); ++ qspi_cs = 0; ++ } ++ priv->bspi_chip_select = (1 << qspi_cs); ++ if (pdata == 0) { ++ struct brcmspi_platform_data platformdata; ++ memset(&platformdata, 0, sizeof(platformdata)); ++ platformdata.flash_cs = qspi_cs; ++ platform_device_add_data(pdev, &platformdata, sizeof(platformdata)); ++ pdata = (struct brcmspi_platform_data *)pdev->dev.platform_data; ++ } ++#else ++ priv->bspi_chip_select = (priv->bspi_hw && pdata) ? (1 << pdata->flash_cs) : 0; ++#endif /* CONFIG_OF */ ++ ++ INIT_LIST_HEAD(&priv->msg_queue); ++ spin_lock_init(&priv->lock); ++ ++ platform_set_drvdata(pdev, priv); ++ ++ tasklet_init(&priv->tasklet, bcmspi_tasklet, (unsigned long)priv); ++ ++ if (!default_master) ++ default_master = master; ++ ++ ++ if (priv->bspi_chip_select) { ++ int bspi_width = BSPI_WIDTH_1BIT; ++ ++ /* Module parameter validation */ ++ if (io_mode != 0) { ++ if (read_opcode < 0 || read_opcode > 255) { ++ dev_err(&pdev->dev, "invalid read_opcode\n"); ++ io_mode = 0; ++ } else if (dummy_cycles < 0 || dummy_cycles > 255) { ++ dev_err(&pdev->dev, "invalid dummy_cycles\n"); ++ io_mode = 0; ++ } ++ } ++ if (io_mode == 2) { ++ bspi_width = BSPI_WIDTH_4BIT; ++ } else if (io_mode == 1) { ++ bspi_width = BSPI_WIDTH_2BIT; ++ } else if (io_mode != 0) { ++ dev_err(&pdev->dev, "invalid io_mode (0/1/2)\n"); ++ } ++ ++ if (io_mode == 2) ++ bcmspi_set_quad_mode(priv, 1); ++ ++ bcmspi_set_mode(priv, bspi_width, BSPI_ADDRLEN_3BYTES, bspi_hp); ++ } ++ ++ ret = spi_register_master(master); ++ if (ret < 0) { ++ dev_err(&pdev->dev, "can't register master\n"); ++ goto err0; ++ } ++ ++ return 0; ++ ++err0: ++ bcmspi_hw_uninit(priv); ++err1: ++#ifdef CONFIG_OF ++ while ( i-- ) { ++ irq = irq_of_parse_and_map(dn, i-1); ++ free_irq(irq, priv); ++ } ++#endif ++err2: ++ if (priv->idm_qspi) { ++ iounmap(priv->idm_qspi); ++ } ++ if (priv->qspi_intr) { ++ iounmap(priv->qspi_intr); ++ } ++ if (priv->bspi_hw_raf) { ++ iounmap(priv->bspi_hw_raf); ++ } ++ if (priv->bspi_hw) { ++ iounmap(priv->bspi_hw); ++ } ++ if (priv->mspi_hw) { ++ iounmap(priv->mspi_hw); ++ } ++ spi_master_put(master); ++ return ret; ++} ++ ++static int bcmspi_remove(struct platform_device *pdev) ++{ ++ struct bcmspi_priv *priv = platform_get_drvdata(pdev); ++ unsigned long flags; ++ u32 irq; ++#ifdef CONFIG_OF ++ struct device_node *dn = pdev->dev.of_node; ++ u32 irq_start=0, irq_end=0; ++#else ++ struct resource *res; ++#endif /* CONFIG_OF */ ++ ++ /* acquire lock when the MSPI is idle */ ++ while (1) { ++ spin_lock_irqsave(&priv->lock, flags); ++ if (priv->state == STATE_IDLE) ++ break; ++ spin_unlock_irqrestore(&priv->lock, flags); ++ udelay(100); ++ } ++ priv->state = STATE_SHUTDOWN; ++ spin_unlock_irqrestore(&priv->lock, flags); ++ ++ tasklet_kill(&priv->tasklet); ++ platform_set_drvdata(pdev, NULL); ++ bcmspi_hw_uninit(priv); ++ if (priv->bspi_hw_raf) ++ iounmap(priv->bspi_hw_raf); ++ if (priv->bspi_hw) ++ iounmap((volatile void __iomem *)priv->bspi_hw); ++#ifdef CONFIG_OF ++ irq_start = irq_of_parse_and_map(dn, 0); ++ irq_end = irq_of_parse_and_map(dn, 1); ++ if (irq_start && irq_end) { ++ for(irq=irq_start; irq<=irq_end; irq++) ++ free_irq(irq, priv); ++ } ++#else ++ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); ++ if (res) { ++ for(irq=(u32)res->start; irq<=(u32)res->end; irq++) { ++ free_irq(irq, priv); ++ } ++ } ++#endif ++ ++ iounmap((volatile void __iomem *)priv->mspi_hw); ++ spi_unregister_master(priv->master); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++static int bcmspi_suspend(struct device *dev) ++{ ++ struct bcmspi_priv *priv = dev_get_drvdata(dev); ++ int ret; ++ ++ if (priv == NULL || priv->master == NULL) { ++ return -EINVAL; ++ } ++ ++ /* Do nothing if it's not yet initialized */ ++ if (!priv->bspi_hw) ++ return 0; ++ ++ /* Flush transactions and stop the queue */ ++ ret = spi_master_suspend(priv->master); ++ if (ret) { ++ dev_warn(dev, "cannot suspend master\n"); ++ return ret; ++ } ++ ++ /* Disable flex mode */ ++ priv->bspi_hw->flex_mode_enable = 0; ++ ++ /* Clear upper byte */ ++ priv->bspi_hw->flash_upper_addr_byte = 0; ++ ++ /* Ensure BSPI read is clean */ ++ bcmspi_flush_prefetch_buffers(priv); ++ ++ /* Switch to BSPI for waking up from boot code */ ++ if (!priv->bspi_enabled) ++ priv->bspi_hw->mast_n_boot_ctrl = 0; ++ ++ return 0; ++}; ++ ++static int bcmspi_resume(struct device *dev) ++{ ++ struct bcmspi_priv *priv = dev_get_drvdata(dev); ++ int ret; ++ ++ if (priv == NULL || priv->master == NULL) ++ return -EINVAL; ++ ++ /* Do nothing if it's not yet initialized */ ++ if (!priv->bspi_hw) ++ return 0; ++ ++ /* Restore MSPI/BSPI mode */ ++ priv->bspi_enabled = !priv->bspi_enabled; ++ if (priv->bspi_enabled) ++ bcmspi_disable_bspi(priv); ++ else ++ bcmspi_enable_bspi(priv); ++ ++ /* Restore controller configuration */ ++ bcmspi_hw_set_parms(priv, &priv->last_parms); ++ ++ /* Restore flex mode configuration */ ++ bcmspi_set_mode(priv, ++ priv->flex_mode.width, priv->flex_mode.addrlen, priv->flex_mode.hp); ++ ++ ++ /* Restore interrupts */ ++ bcmspi_disable_interrupt(priv, 0xffffffff); ++ bcmspi_clear_interrupt(priv, 0xffffffff); ++ bcmspi_enable_interrupt(priv, QSPI_INTR_MSPI_DONE_MASK); ++ ++ /* Ensure BSPI read is clean */ ++ bcmspi_flush_prefetch_buffers(priv); ++ ++ /* Start the queue running */ ++ ret = spi_master_resume(priv->master); ++ if (ret) ++ dev_err(dev, "problem starting queue (%d)\n", ret); ++ ++ return ret; ++} ++ ++static const struct dev_pm_ops bcmspi_pm_ops = { ++ .suspend = bcmspi_suspend, ++ .resume = bcmspi_resume, ++}; ++#endif /* CONFIG_PM */ ++ ++ ++#ifdef CONFIG_OF ++static const struct of_device_id qspi_iproc_dt_ids[] = { ++ {.compatible = "brcm,iproc-qspi"}, ++ {}, ++}; ++ ++MODULE_DEVICE_TABLE(of, qspi_iproc_dt_ids); ++ ++ ++static struct platform_driver qspi_iproc_driver = { ++ .driver = { ++ .name = "iproc-qspi", ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(qspi_iproc_dt_ids), ++#ifdef CONFIG_PM ++ .pm = &bcmspi_pm_ops, ++#endif ++ }, ++ .probe = bcmspi_probe, ++ .remove = bcmspi_remove, ++}; ++ ++module_platform_driver(qspi_iproc_driver); ++ ++#else /*CONFIG_OF*/ ++ ++static struct platform_driver driver = { ++ .driver = { ++ .name = "qspi_iproc", ++ .bus = &platform_bus_type, ++ .owner = THIS_MODULE, ++#ifdef CONFIG_PM ++ .pm = &bcmspi_pm_ops, ++#endif ++ }, ++ .probe = bcmspi_probe, ++ .remove = __devexit_p(bcmspi_remove), ++}; ++ ++static int __init bcmspi_spi_init(void) ++{ ++ platform_driver_register(&driver); ++ return 0; ++} ++ ++static void __exit bcmspi_spi_exit(void) ++{ ++ platform_driver_unregister(&driver); ++} ++ ++module_init(bcmspi_spi_init); ++module_exit(bcmspi_spi_exit); ++#endif /*CONFIG_OF*/ ++ ++MODULE_AUTHOR("Broadcom Corporation"); ++MODULE_DESCRIPTION("iProc QSPI driver"); ++MODULE_LICENSE("GPL"); +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/usb/gadget/legacy/serial.c b/drivers/usb/gadget/legacy/serial.c +--- a/drivers/usb/gadget/legacy/serial.c 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/usb/gadget/legacy/serial.c 2017-11-09 17:54:01.552429000 +0800 +@@ -250,7 +250,7 @@ static int __init init(void) + */ + if (use_acm) { + serial_config_driver.label = "CDC ACM config"; +- serial_config_driver.bConfigurationValue = 2; ++ serial_config_driver.bConfigurationValue = 1; + device_desc.bDeviceClass = USB_CLASS_COMM; + device_desc.idProduct = + cpu_to_le16(GS_CDC_PRODUCT_ID); +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig +--- a/drivers/usb/gadget/udc/Kconfig 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/usb/gadget/udc/Kconfig 2017-11-09 17:54:01.588427000 +0800 +@@ -373,6 +373,17 @@ config USB_GADGET_XILINX + dynamically linked module called "udc-xilinx" and force all + gadget drivers to also be dynamically linked. + ++config USB_XGS_IPROC_UDC ++ tristate "Broadcom XGS IPROC USB Device driver" ++ depends on ARCH_XGS_IPROC && USB_GADGET ++ default n ++ help ++ USB peripheral controller driver for Broadcom XGS IPROC USB 2 device. ++ ++ Say "y" to link the driver statically, or "m" to build a dynamically ++ linked module called "xgs_iproc_udc" and force all gadget drivers to ++ also be dynamically linked. ++ + # + # LAST -- dummy/emulated controller + # +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/usb/gadget/udc/Makefile b/drivers/usb/gadget/udc/Makefile +--- a/drivers/usb/gadget/udc/Makefile 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/usb/gadget/udc/Makefile 2017-11-09 17:54:01.589418000 +0800 +@@ -30,4 +30,5 @@ obj-$(CONFIG_USB_FOTG210_UDC) += fotg210 + obj-$(CONFIG_USB_MV_U3D) += mv_u3d_core.o + obj-$(CONFIG_USB_GR_UDC) += gr_udc.o + obj-$(CONFIG_USB_GADGET_XILINX) += udc-xilinx.o ++obj-$(CONFIG_USB_XGS_IPROC_UDC) += xgs_iproc_udc.o + obj-$(CONFIG_USB_BDC_UDC) += bdc/ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/usb/gadget/udc/xgs_iproc_udc.c b/drivers/usb/gadget/udc/xgs_iproc_udc.c +--- a/drivers/usb/gadget/udc/xgs_iproc_udc.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/usb/gadget/udc/xgs_iproc_udc.c 2017-11-09 17:54:01.736429000 +0800 +@@ -0,0 +1,2114 @@ ++/***************************************************************************** ++* Copyright 2006 - 2010 Broadcom Corporation. All rights reserved. ++* ++* Unless you and Broadcom execute a separate written software license ++* agreement governing use of this software, this software is licensed to you ++* under the terms of the GNU General Public License version 2, available at ++* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). ++* ++* Notwithstanding the above, under no circumstances may you combine this ++* software in any way with any other Broadcom software provided under a ++* license other than the GPL, without Broadcom's express prior written ++* consent. ++*****************************************************************************/ ++/****************************************************************************/ ++/** ++* @file bcm_dwc_udc.c ++* ++* @brief Broadcom Linux driver for DWC USB 2.0 Device Controller (UDC) ++* ++* This driver implements the Linux Gadget driver API as defined in usb_gadget.h ++* ++* @note ++* ++* This driver was written with the intent of being able to support any ++* variations on how this block is integrated into different Broadcom chips. ++* ++* There is a requirement on how the DWC UDC is configured. In particular, this ++* driver requires that the following options be defined and enabled in the ++* UDC core. ++* ++* UDC20AHB_CNAK_CLR_ENH_CC ++* UDC20AHB_STALL_SET_ENH_CC ++* UDC20AHB_SNAK_ENH_CC ++* ++* Some other UDC attributes can be supported by setting compile time options ++* or with some minor modifications to the source code. Ideally these would ++* be run-time info that is provided by the device instance to the driver. ++* These attributes include the following. ++* ++* IPROC_UDC_EP_CNT ++* IPROC_UDC_EP_MAX_PKG_SIZE ++* Type of each endpoint: Control, IN, OUT, or Bidirectional ++*/ ++/****************************************************************************/ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "xgs_iproc_udc.h" ++ ++#define XGS_IPROC_UDC_NAME "iproc-udc" ++/* Would be nice if DMA_ADDR_INVALID or similar was defined in dma-mapping.h */ ++#define DMA_ADDR_INVALID (~(dma_addr_t)0) ++/* ++ * FRAME_NUM_INVALID is used for ISOC IN transfers for frame alignment. ++ * The device specifies the interval at which it wants to do transfers, ++ * but the host initiates all transfers. If the interval is some multiple ++ * number of frames, the device has no idea which frame in an interval ++ * window the host is going to start transfers. This could even be at a ++ * point many frames beyond the current window, as the starting point ++ * can be very application dependant and subject to an indeterminate ++ * amount of latency. ++ */ ++#define FRAME_NUM_INVALID (~(uint)0) ++/* Would be nice if ENOERROR or similar was defined in errno.h */ ++#define ENOERROR 0 ++ ++/* ---- Private Function Prototypes -------------------------------------- */ ++#ifdef IPROC_UDC_DEBUG ++static void iproc_dbg_dma_dump(struct iproc_udc *udc); ++static void iproc_dbg_dma_dump_desc(char *label, struct iproc_udc_dma_desc *virt, struct iproc_udc_dma_desc *phys); ++static void iproc_dbg_dma_dump_ep(struct iproc_ep *ep); ++#endif /* IPROC_UDC_DEBUG */ ++ ++static void iproc_ep_setup_init(struct iproc_ep *ep, int status); ++static void iproc_ep_setup_process(struct iproc_ep *ep, struct usb_ctrlrequest *setup); ++ ++static void iproc_dma_ep_init(struct iproc_ep *ep); ++static void iproc_dma_data_init(struct iproc_ep *ep); ++static void iproc_dma_data_finish(struct iproc_ep *ep); ++static void iproc_dma_data_add_ready(struct iproc_ep *ep); ++static void iproc_dma_data_rm_done(struct iproc_ep *ep); ++ ++static int iproc_platform_dma_alloc(struct platform_device *platformDevP, struct iproc_udc *udc); ++static void iproc_platform_dma_free(struct platform_device *platformDevP, struct iproc_udc *udc); ++ ++static void iproc_udc_req_queue_flush(struct iproc_ep *ep, int status); ++static void iproc_udc_req_xfer_error(struct iproc_ep *ep, int status); ++static void iproc_udc_req_xfer_done(struct iproc_ep *ep, struct iproc_ep_req *req, int status); ++static void iproc_udc_req_xfer_process(struct iproc_ep *ep); ++static void iproc_udc_req_xfer_add(struct iproc_ep *ep, struct iproc_ep_req *req); ++ ++static void iproc_udc_ops_finish(struct iproc_udc *udc); ++static void iproc_udc_ops_init(struct iproc_udc *udc); ++static void iproc_udc_ops_stop(struct iproc_udc *udc); ++static void iproc_udc_ops_start(struct iproc_udc *udc); ++static void iproc_udc_ops_disconnect(struct iproc_udc *udc); ++static void iproc_udc_ops_shutdown(struct iproc_udc *udc); ++ ++static int xgs_iproc_ep_enable(struct usb_ep *ep, const struct usb_endpoint_descriptor *desc); ++static int xgs_iproc_ep_disable(struct usb_ep *ep); ++static struct usb_request *xgs_iproc_ep_alloc_request(struct usb_ep *ep, uint gfp_flags); ++static void xgs_iproc_ep_free_request(struct usb_ep *ep, struct usb_request *req); ++static int xgs_iproc_ep_queue(struct usb_ep *ep, struct usb_request *req, uint gfp_flags); ++static int xgs_iproc_ep_dequeue(struct usb_ep *ep, struct usb_request *req); ++static int xgs_iproc_ep_set_halt(struct usb_ep *ep, int value); ++static int xgs_iproc_ep_fifo_status(struct usb_ep *ep); ++static void xgs_iproc_ep_fifo_flush(struct usb_ep *ep); ++ ++static int xgs_iproc_udc_start(struct usb_gadget *, struct usb_gadget_driver *); ++static int xgs_iproc_udc_stop(struct usb_gadget *); ++ ++static int xgs_iproc_udc_probe(struct platform_device *pdev); ++static int xgs_iproc_udc_remove(struct platform_device *pdev); ++ ++static void xgs_iproc_udc_proc_create(void); ++static void xgs_iproc_udc_proc_remove(void); ++ ++/* ---- Private Variables ------------------------------------------------ */ ++static const struct { ++ const char *name; ++ const int type; ++ const int msize; ++ const struct usb_ep_caps caps; ++} xgs_iproc_ep_info[] = { ++#define EP_INFO(_name, _type, _size, _caps) \ ++ { \ ++ .name = _name, \ ++ .type = _type, \ ++ .msize = _size, \ ++ .caps = _caps, \ ++ } ++ ++ EP_INFO("ep0", USB_ENDPOINT_XFER_CONTROL, IPROC_UDC_CTRL_MAX_PKG_SIZE, ++ USB_EP_CAPS(USB_EP_CAPS_TYPE_CONTROL, USB_EP_CAPS_DIR_ALL)), ++ EP_INFO("ep1in", USB_ENDPOINT_XFER_ISOC, IPROC_UDC_EP_MAX_PKG_SIZE, ++ USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO, USB_EP_CAPS_DIR_IN)), ++ EP_INFO("ep2out", USB_ENDPOINT_XFER_ISOC, IPROC_UDC_EP_MAX_PKG_SIZE, ++ USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO, USB_EP_CAPS_DIR_OUT)), ++ EP_INFO("ep3in", USB_ENDPOINT_XFER_BULK, IPROC_UDC_EP_MAX_PKG_SIZE, ++ USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_IN)), ++ EP_INFO("ep4out", USB_ENDPOINT_XFER_BULK, IPROC_UDC_EP_MAX_PKG_SIZE, ++ USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_OUT)), ++ EP_INFO("ep5in", USB_ENDPOINT_XFER_INT, IPROC_UDC_EP_MAX_PKG_SIZE, ++ USB_EP_CAPS(USB_EP_CAPS_TYPE_INT, USB_EP_CAPS_DIR_IN)), ++ EP_INFO("ep6out", USB_ENDPOINT_XFER_INT, IPROC_UDC_EP_MAX_PKG_SIZE, ++ USB_EP_CAPS(USB_EP_CAPS_TYPE_INT, USB_EP_CAPS_DIR_OUT)), ++#undef EP_INFO ++}; ++ ++static struct usb_gadget_ops xgs_iproc_udc_ops = { ++ .udc_start = xgs_iproc_udc_start, ++ .udc_stop = xgs_iproc_udc_stop, ++}; ++ ++static struct usb_ep_ops xgs_iproc_udc_ep_ops = { ++ .enable = xgs_iproc_ep_enable, ++ .disable = xgs_iproc_ep_disable, ++ .alloc_request = xgs_iproc_ep_alloc_request, ++ .free_request = xgs_iproc_ep_free_request, ++ .queue = xgs_iproc_ep_queue, ++ .dequeue = xgs_iproc_ep_dequeue, ++ .set_halt = xgs_iproc_ep_set_halt, ++ .fifo_status = xgs_iproc_ep_fifo_status, ++ .fifo_flush = xgs_iproc_ep_fifo_flush, ++}; ++ ++/*********************************************************************** ++ * Convenience functions ++ ***********************************************************************/ ++static inline struct iproc_udc *gadget_to_udc(struct usb_gadget *g) ++{ ++ return container_of(g, struct iproc_udc, gadget); ++} ++ ++static inline struct iproc_ep *our_ep(struct usb_ep *ep) ++{ ++ return container_of(ep, struct iproc_ep, usb_ep); ++} ++ ++static inline struct iproc_ep_req *our_req(struct usb_request *req) ++{ ++ return container_of(req, struct iproc_ep_req, usb_req); ++} ++ ++/**************************************************************************** ++ * DMA descriptor chain routines. ++ * ++ * dma_desc_chain_reset - Initialize chain in preparation for transfer ++ * dma_desc_chain_full - Indicates if no descriptors in chain for available for use. ++ * dma_desc_chain_alloc - Get next free descriptor for use. Have to check if chain not full first. ++ * dma_desc_chain_empty - Indicates if no descriptors in the chain are being used. ++ * dma_desc_chain_head - Pointer to 1st entry in chain. Have to check if chain not empty first. ++ * dma_desc_chain_free - Frees up 1st entry for use. Only do this if DMA for this descriptor has completed. ++ * ++ ***************************************************************************/ ++static inline struct iproc_udc_dma_desc *dma_desc_chain_alloc(struct iproc_ep *ep) ++{ ++ uint idx; ++ ++ idx = ep->dma.add_idx++; ++ ++ return &ep->dma.vir_addr->desc[IPROC_EP_DMA_DESC_IDX(idx)]; ++} ++ ++static inline int dma_desc_chain_empty(struct iproc_ep *ep) ++{ ++ return ep->dma.add_idx == ep->dma.rm_idx; ++} ++ ++static inline void dma_desc_chain_free(struct iproc_ep *ep) ++{ ++ ep->dma.rm_idx++; ++} ++ ++static inline int dma_desc_chain_full(struct iproc_ep *ep) ++{ ++ return (!dma_desc_chain_empty(ep) && (IPROC_EP_DMA_DESC_IDX(ep->dma.add_idx) == IPROC_EP_DMA_DESC_IDX(ep->dma.rm_idx))); ++} ++ ++static inline struct iproc_udc_dma_desc *dma_desc_chain_head(struct iproc_ep *ep) ++{ ++ return (&ep->dma.vir_addr->desc[IPROC_EP_DMA_DESC_IDX(ep->dma.rm_idx)]); ++} ++ ++static inline void dma_desc_chain_reset(struct iproc_ep *ep) ++{ ++ ep->dma.add_idx = 0; ++ ep->dma.rm_idx = 0; ++} ++ ++ ++/**************************************************************************** ++ * APIs used by a Gadget driver to attach / detach from the UDC driver. ++ ***************************************************************************/ ++static int xgs_iproc_udc_start(struct usb_gadget *gadget, ++ struct usb_gadget_driver *gadget_driver) ++{ ++ struct iproc_udc *udc = gadget_to_udc(gadget); ++ ulong flags; ++ ++ if (!udc) { ++ dev_err(udc->dev, "UDC driver not initialized\n"); ++ return -ENODEV; ++ } ++ ++ if (!gadget_driver || !gadget_driver->setup || ++ gadget_driver->max_speed < USB_SPEED_FULL) { ++ dev_err(udc->dev, "invalid gadget driver\n" ); ++ return -EINVAL; ++ } ++ ++ spin_lock_irqsave(&udc->lock, flags); ++ ++ if (udc->gadget_driver) { ++ spin_unlock_irqrestore(&udc->lock, flags); ++ dev_err(udc->dev, "UDC driver busy\n"); ++ return -EBUSY; ++ } ++ ++ /* Hook up the gadget driver to the UDC controller driver */ ++ gadget_driver->driver.bus = NULL; ++ udc->gadget_driver = gadget_driver; ++ udc->gadget.dev.driver = &gadget_driver->driver; ++ udc->pullup_on = 1; ++ ++ iproc_udc_ops_start(udc); ++ /* un-stop the control endpoint */ ++ udc->ep[0].stopped = 0; ++ iproc_usbd_bus_conn(udc->usbd_regs); ++ ++ iproc_usbd_setup_done(udc->usbd_regs); ++ iproc_usbd_dma_en(udc->usbd_regs); ++ ++ spin_unlock_irqrestore(&udc->lock, flags); ++ ++ return ENOERROR; ++} ++ ++static int xgs_iproc_udc_stop(struct usb_gadget *gadget) ++{ ++ ulong flags; ++ struct iproc_udc *udc = gadget_to_udc(gadget); ++ ++ if (!udc) { ++ dev_err(udc->dev, "UDC driver not initialized\n"); ++ return -ENODEV; ++ } ++ ++ spin_lock_irqsave(&udc->lock, flags); ++ ++ udc->ep[0].stopped = 1; ++ iproc_udc_ops_stop(udc); ++ udelay(20); ++ udc->pullup_on = 0; ++ iproc_usbd_bus_disconn(udc->usbd_regs); ++ iproc_udc_ops_shutdown(udc); ++ spin_unlock_irqrestore(&udc->lock, flags); ++ ++ return ENOERROR; ++} ++ ++/**************************************************************************** ++ * ++ * Platform device level alloc / free of memory used for DMA descriptors. ++ * A single block of memory static in size is used for DMA descriptors. ++ * Each endpoint has a small number of descriptors for its exclusive use. ++ * These are chained in a loop. See bcm_udc_dwc.h and iproc_dma_ep_init() for more ++ * details. ++ * ++ ***************************************************************************/ ++static int iproc_platform_dma_alloc(struct platform_device *platformDevP, struct iproc_udc *udc) ++{ ++ udc->dma.vir_addr = dma_alloc_coherent(&platformDevP->dev, sizeof(struct iproc_udc_dma), ++ (dma_addr_t *)&udc->dma.phy_addr, GFP_KERNEL); ++ ++ if (!udc->dma.vir_addr) { ++ dev_err(udc->dev, "dma_alloc_coherent() failed\n"); ++ return -ENOMEM; ++ } ++ ++ return ENOERROR; ++} ++ ++static void iproc_platform_dma_free(struct platform_device *platformDevP, struct iproc_udc *udc) ++{ ++ int idx; ++ ++ dma_free_coherent(&platformDevP->dev, sizeof(struct iproc_udc_dma), udc->dma.vir_addr, ++ (dma_addr_t)udc->dma.phy_addr); ++ ++ for (idx = 0; idx < IPROC_UDC_EP_CNT; idx ++) { ++ if (udc->ep[idx].dma.align_buff) { ++ dma_free_coherent(NULL, udc->ep[idx].dma.align_len, ++ udc->ep[idx].dma.align_buff, ++ udc->ep[idx].dma.align_addr); ++ udc->ep[idx].dma.align_buff = NULL; ++ } ++ } ++} ++ ++/**************************************************************************** ++ * Linux Gadget endpoint operations. See usb_ep_ops in usb_gadget.h. ++ ***************************************************************************/ ++static int xgs_iproc_ep_enable(struct usb_ep *usb_ep, const struct usb_endpoint_descriptor *desc) ++{ ++ struct iproc_ep *ep = our_ep(usb_ep); ++ struct iproc_udc *udc = ep->udc; ++ ulong flags; ++ uint xferType; ++ int ret = ENOERROR; ++ ++ if (!usb_ep || (ep->beq_addr != desc->bEndpointAddress)) { ++ dev_err(udc->dev, "invalid endpoint (%p)\n", usb_ep); ++ return -EINVAL; ++ } ++ ++ if (!desc || (desc->bDescriptorType != USB_DT_ENDPOINT)) { ++ dev_err(udc->dev, "ep%d: invalid descriptor=%p type=%d\n", ep->num, desc, desc ? desc->bDescriptorType : -1); ++ return -EINVAL; ++ } ++ ++ if (desc == ep->desc) { ++ dev_warn(udc->dev, "ep%d: already enabled with same descriptor\n", ep->num); ++ return -EEXIST; ++ } ++ ++ if (ep->desc) { ++ dev_warn(udc->dev, "ep%d: already enabled with another descriptor\n", ep->num); ++ return -EBUSY; ++ } ++ ++ if (!udc->gadget_driver || (udc->gadget.speed == USB_SPEED_UNKNOWN)) { ++ dev_warn(udc->dev, "%s: invalid device state\n", ep->usb_ep.name); ++ return -ESHUTDOWN; ++ } ++ ++ xferType = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; ++ if ((ep->dir == USB_DIR_IN) && (xferType == USB_ENDPOINT_XFER_ISOC)) { ++ if ((desc->bInterval < 1) || (desc->bInterval > 16)) { ++ dev_err(udc->dev, "%s: invalid ISOC bInterval=%u\n", ep->usb_ep.name, desc->bInterval); ++ return -ERANGE; ++ } ++ ++ /* ++ * We don't know when the host will send the first ISO IN request, so we need to set up ++ * to capture that event so we can align subsequent transfers to that particular frame ++ * number. Also set the frame number increment. The endpoint descriptor specifies this ++ * as a power of 2 (2**(n-1)). Translate this into a specific number of frames. ++ */ ++ ep->dma.frame_num = FRAME_NUM_INVALID; ++ ep->dma.frame_incr = 1 << (desc->bInterval - 1); ++ } ++ ++ spin_lock_irqsave(&udc->lock, flags); ++ ++ ep->desc = desc; ++ ep->stopped = 0; ++ ++ /** @todo Rework the UdcEpCfg() so it includes iproc_usbd_ep_cfg_set() ... */ ++ iproc_usbd_ep_cfg_set(udc->usbd_regs, ep->num, iproc_usbd_cfg_num(udc->usbd_regs)); ++ ++ spin_unlock_irqrestore(&udc->lock, flags); ++ ++ return ret; ++} ++ ++static int xgs_iproc_ep_disable(struct usb_ep *usb_ep) ++{ ++ struct iproc_ep *ep = our_ep(usb_ep); ++ struct iproc_udc *udc = ep->udc; ++ ulong flags; ++ int ret = ENOERROR; ++ ++ if (!usb_ep) { ++ dev_err(udc->dev, "invalid endpoint\n"); ++ return -EINVAL; ++ } ++ ++ if (!ep->desc) { ++ dev_warn(udc->dev, "%s: already disabled\n", ep->usb_ep.name); ++ return ENOERROR; ++ } ++ ++ spin_lock_irqsave(&udc->lock, flags); ++ ++ iproc_udc_req_queue_flush(ep, -ESHUTDOWN); ++ iproc_usbd_ep_irq_dis(udc->usbd_regs, ep->num, ep->dir); ++ ep->desc = NULL; ++ ++ spin_unlock_irqrestore(&udc->lock, flags); ++ ++ return ret; ++} ++ ++struct usb_request * xgs_iproc_ep_alloc_request(struct usb_ep *usb_ep, uint gfp_flags) ++{ ++ struct iproc_ep_req *req; ++ ++ if (!usb_ep) { ++ return NULL; ++ } ++ ++ if ((req = kzalloc(sizeof(*req), gfp_flags)) != NULL) { ++ /* ++ * Set the usb_req.dma to DMA_ADDR_INVALID so it can be determined if the usb_req.buf needs ++ * to be mapped when the request is subsequently queued. ++ */ ++ INIT_LIST_HEAD(&req->list_node); ++ req->usb_req.dma = DMA_ADDR_INVALID; ++ ++ return &req->usb_req; ++ } ++ ++ return NULL; ++} ++ ++static void xgs_iproc_ep_free_request(struct usb_ep *usb_ep, struct usb_request *usb_req) ++{ ++ struct iproc_ep_req *req = our_req(usb_req); ++ ++ if (usb_req) { ++ kfree(req); ++ } ++} ++ ++static int xgs_iproc_ep_queue(struct usb_ep *usb_ep, struct usb_request *usb_req, uint gfp_flags) ++{ ++ struct iproc_ep *ep = our_ep(usb_ep); ++ struct iproc_udc *udc = ep->udc; ++ struct iproc_ep_req *req = our_req(usb_req); ++ ulong flags; ++ int ret = ENOERROR; ++ ++ if (!usb_ep || !usb_req || !req->usb_req.complete || !req->usb_req.buf || !list_empty(&req->list_node)) { ++ dev_err(udc->dev, "invalid request\n"); ++ return -EINVAL; ++ } ++ ++ if (!ep->desc && (ep->num != 0)) { ++ dev_err(udc->dev, "%s: invalid EP state\n", ep->usb_ep.name); ++ return -EFAULT; ++ } ++ ++ if ((ep->type == USB_ENDPOINT_XFER_CONTROL) && !list_empty(&ep->list_queue)) { ++ dev_err(udc->dev, "%s: CTRL EP queue not empty\n", ep->usb_ep.name); ++ return -EPERM; ++ } ++ ++ if (usb_req->length > 16384 /* FSG_BUFLEN */) { ++ dev_err(udc->dev, "%s: request too big, length=%u\n", ep->usb_ep.name, usb_req->length); ++ return -E2BIG; ++ } ++ ++ /* ++ * Restrict ISOC IN requests to the max packet size. Assumption is that it does not make ++ * much sense to have more than one interval's (scheduled bandwidth's) worth of data. ++ */ ++ if ((ep->type == USB_ENDPOINT_XFER_ISOC) && (ep->dir == USB_DIR_IN) && (usb_req->length > ep->usb_ep.maxpacket)) { ++ dev_err(udc->dev, "%s: request > scheduled bandwidth, length=%u\n", ep->usb_ep.name, usb_req->length); ++ return -EFBIG; ++ } ++ ++ if (!udc->gadget_driver || (udc->gadget.speed == USB_SPEED_UNKNOWN)) { ++ dev_warn(udc->dev, "%s: invalid device state\n", ep->usb_ep.name); ++ return -ESHUTDOWN; ++ } ++ ++ if (((ulong)req->usb_req.buf) & 0x3UL) { ++ /* ++ * The DMA buffer does not have the alignment required by the hardware. We keep an endpoint level ++ * buffer available to handle this situation if it arises. If we don't currently have one available ++ * for this purpose, or if the current one is not large enough, then allocate a new one. Since ++ * we only have one buffer, we won't copy into the buffer until we are ready to do the DMA transfer. ++ * Mark the request as needing this alignment (copy). ++ */ ++ if ((ep->dma.align_buff != NULL) && (ep->dma.align_len < req->usb_req.length)) { ++ dma_free_coherent(NULL, ep->dma.align_len, ep->dma.align_buff, ep->dma.align_addr); ++ ep->dma.align_buff = NULL; ++ } ++ ++ if (ep->dma.align_buff == NULL) { ++ ep->dma.align_len = req->usb_req.length; ++ ep->dma.align_buff = dma_alloc_coherent(NULL, ep->dma.align_len, &(ep->dma.align_addr), GFP_KERNEL); ++ } ++ ++ if (ep->dma.align_buff == NULL) { ++ dev_err(udc->dev, "%s: dma_alloc_coherent() failed, length=%u\n", ep->usb_ep.name, usb_req->length); ++ return -ENOMEM; ++ } ++ ++ req->dma_aligned = 1; ++ } else if ((req->usb_req.dma == DMA_ADDR_INVALID) || (req->usb_req.dma == 0)) { ++ /* A physical address was not provided for the DMA buffer, so request it. */ ++ req->dma_mapped = 1; ++ req->usb_req.dma = dma_map_single(udc->gadget.dev.parent, ++ req->usb_req.buf, ++ req->usb_req.length, ++ (ep->dir == USB_DIR_IN ? DMA_TO_DEVICE : DMA_FROM_DEVICE)); ++ } ++ ++ spin_lock_irqsave(&udc->lock, flags); ++ ++ req->usb_req.status = -EINPROGRESS; ++ req->usb_req.actual = 0; ++ ++ if ((ep->type == USB_ENDPOINT_XFER_CONTROL) && (ep->dir == USB_DIR_OUT) && (req->usb_req.length == 0)) { ++ /* ++ * This might happen if gadget driver decides to send zero length packet (ZLP) during STATUS phase ++ * of a control transfer. This may happen for the cases where there is not a DATA phase. Just consider ++ * things complete. ZLP will be issued by hardware. See the handling of SETUP packets for more details ++ * on control transfer processing. ++ */ ++ iproc_udc_req_xfer_done(ep, req, ENOERROR); ++ } else { ++ if (req->usb_req.length == 0) { ++ req->usb_req.zero = 1; ++ } ++ iproc_udc_req_xfer_add(ep, req); ++ } ++ ++ spin_unlock_irqrestore(&udc->lock, flags); ++ ++ return ret; ++} ++ ++static int xgs_iproc_ep_dequeue(struct usb_ep *usb_ep, struct usb_request *usb_req) ++{ ++ struct iproc_ep *ep = our_ep(usb_ep); ++ struct iproc_udc *udc = ep->udc; ++ struct iproc_ep_req *req = our_req(usb_req); ++ ulong flags; ++ int ret = ENOERROR; ++ ++ if (!usb_ep || !usb_req) { ++ dev_err(udc->dev, "invalid request\n"); ++ return -EINVAL; ++ } ++ ++ spin_lock_irqsave(&udc->lock, flags); ++ ++ /* Make sure it's actually queued on this endpoint */ ++ list_for_each_entry(req, &ep->list_queue, list_node) { ++ if (&req->usb_req == usb_req) { ++ break; ++ } ++ } ++ ++ if (&req->usb_req != usb_req) { ++ spin_unlock_irqrestore(&udc->lock, flags); ++ dev_err(udc->dev, "%s: request not queued\n", ep->usb_ep.name); ++ return -ENOLINK; ++ } ++ ++ /** @todo Handle case where the request is in progress, or completed but not dequeued */ ++ ++ iproc_udc_req_xfer_done(ep, req, -ECONNRESET); ++ spin_unlock_irqrestore(&udc->lock, flags); ++ ++ return ret; ++} ++ ++static int xgs_iproc_ep_set_halt(struct usb_ep *usb_ep, int enable) ++{ ++ struct iproc_ep *ep = our_ep(usb_ep); ++ struct iproc_udc *udc = ep->udc; ++ ulong flags; ++ int ret = ENOERROR; ++ ++ if (!usb_ep) { ++ dev_err(udc->dev, "invalid request\n"); ++ return -EINVAL; ++ } ++ ++ if (ep->type == USB_ENDPOINT_XFER_ISOC) { ++ dev_warn(udc->dev, "%s: ISO HALT operations not supported\n", ep->usb_ep.name); ++ return -EOPNOTSUPP; ++ } ++ ++ if (enable && (ep->dir == USB_DIR_IN) && !list_empty(&ep->list_queue)) { ++ /* Only allow halt on an IN EP if its queue is empty */ ++ dev_err(udc->dev, "%s: IN queue not empty\n", ep->usb_ep.name); ++ return -EAGAIN; ++ } ++ ++ if (!enable && (ep->type == USB_ENDPOINT_XFER_CONTROL)) { ++ /* ++ * Halt clear for a control EP should only be handled as part of the subsequent SETUP ++ * exchange that occurs after the Halt was set. ++ */ ++ dev_warn(udc->dev, "%s: CTRL HALT clear\n", ep->usb_ep.name); ++ return -EPROTO; ++ } ++ ++ spin_lock_irqsave(&udc->lock, flags); ++ ++ if (!enable) { ++ iproc_usbd_ep_stall_dis(udc->usbd_regs, ep->num, ep->dir); ++ } else if (ep->type != USB_ENDPOINT_XFER_CONTROL) { ++ iproc_usbd_ep_stall_en(udc->usbd_regs, ep->num, ep->dir); ++ } else { ++ iproc_usbd_ep_stall_en(udc->usbd_regs, ep->num, USB_DIR_IN); ++ iproc_usbd_ep_stall_en(udc->usbd_regs, ep->num, USB_DIR_OUT); ++ } ++ ++ spin_unlock_irqrestore(&udc->lock, flags); ++ mdelay(2); ++ ++ return ret; ++} ++ ++static int xgs_iproc_ep_fifo_status(struct usb_ep *usb_ep) ++{ ++ /* ++ * The DWC UDC core doesn't have a mechanism for determining the number of bytes ++ * currently in a FIFO. The best that can be done is determine whether or not a ++ * FIFO is empty. However, for the situation where a single Rx FIFO is being ++ * used for all endpoints, if cannot be determined which OUT and CTRL EP's are ++ * affected if the Rx FIFO is not empty. ++ */ ++ return -EOPNOTSUPP; ++} ++ ++static void xgs_iproc_ep_fifo_flush(struct usb_ep *usb_ep) ++{ ++ struct iproc_ep *ep = our_ep(usb_ep); ++ struct iproc_udc *udc = ep->udc; ++ ulong flags; ++ ++ if (!usb_ep) { ++ dev_err(udc->dev, "invalid request\n"); ++ return; ++ } ++ ++ /* ++ * FIFO flush for a control EP does not make any sense. The SETUP protocol ++ * should eliminate the need to flush. ++ */ ++ if (ep->type == USB_ENDPOINT_XFER_CONTROL) { ++ dev_warn(udc->dev, "%s: CTRL FIFO flush\n", ep->usb_ep.name); ++ return; ++ } ++ ++ if (iproc_usbd_ep_fifo_empty(udc->usbd_regs, ep->num, ep->dir)) { ++ dev_warn(udc->dev, "%s: FIFO empty\n", ep->usb_ep.name); ++ return; ++ } ++ ++ spin_lock_irqsave(&udc->lock, flags); ++ ++ iproc_usbd_ep_fifo_flush_en(udc->usbd_regs, ep->num, ep->dir); ++ ++ spin_unlock_irqrestore(&udc->lock, flags); ++} ++ ++/*************************************************************************** ++ * Routines for debug dump of DMA descriptors ++ **************************************************************************/ ++#ifdef IPROC_UDC_DEBUG ++static void iproc_dbg_dma_dump(struct iproc_udc *udc) ++{ ++ int idx; ++ ++ for (idx = 0; idx < IPROC_UDC_EP_CNT; idx++) { ++ iproc_dbg_dma_dump_ep(&udc->ep[idx]); ++ } ++} ++ ++static void iproc_dbg_dma_dump_desc(char *label, struct iproc_udc_dma_desc *virt, struct iproc_udc_dma_desc *phys) ++{ ++ printk("%s virt=0x%p phys=0x%p: 0x%08x 0x%08x 0x%08x", label, virt, phys, virt->status, virt->reserved, virt->buf_addr); ++} ++ ++static void iproc_dbg_dma_dump_ep(struct iproc_ep *ep) ++{ ++ int idx; ++ ++ printk("EP %d DMA\n", ep->num); ++ printk(" setup\n"); ++ iproc_dbg_dma_dump_desc(" ", (struct iproc_udc_dma_desc *)&ep->dma.vir_addr->setup, (struct iproc_udc_dma_desc *)&ep->dma.phy_addr->setup); ++ printk(" desc\n"); ++ ++ for (idx = 0; idx < IPROC_EP_DMA_DESC_CNT; idx++) { ++ iproc_dbg_dma_dump_desc(" ", &ep->dma.vir_addr->desc[idx], &ep->dma.phy_addr->desc[idx]); ++ ++ /* Don't bother displaying entries beyond the last. */ ++ if (IPROC_USBD_READ(ep->dma.vir_addr->desc[idx].status) & IPROC_USBD_REG_DMA_STAT_LAST_DESC) { ++ break; ++ } ++ } ++} ++#endif /* IPROC_UDC_DEBUG */ ++ ++/**************************************************************************** ++ * Initialization of DMA descriptors at the endpoint level. ++ ***************************************************************************/ ++static void iproc_dma_ep_init(struct iproc_ep *ep) ++{ ++ struct iproc_udc *udc = ep->udc; ++ int idx; ++ ++ /** @todo shorten names to virtAddr physAddr?? */ ++ ep->dma.vir_addr = &udc->dma.vir_addr->ep[ep->num]; ++ ep->dma.phy_addr = &udc->dma.phy_addr->ep[ep->num]; ++ ++ /* ++ * Control endpoints only do setup in the OUT direction, so only need to set the ++ * buffer address for that direction. The buffer is set, even if not a control ++ * endpoint, just to simplify things. There's no harm with this. ++ */ ++ ep->dma.vir_addr->setup.status = cpu_to_le32(IPROC_USBD_REG_DMA_STAT_BUF_HOST_BUSY); ++ wmb(); ++ iproc_usbd_ep_dma_buf_addr_set(udc->usbd_regs, ep->num, USB_DIR_OUT, &ep->dma.phy_addr->setup); ++ ++ /* ++ * Take ownership of the DMA descriptors, and chain them in a loop. This allows a small number ++ * descriptors to be used for requests. Need to have the DWC DMA Descriptor Update option enabled ++ * in the device control register in order to do this. When a transfer for a descriptor completes, ++ * the descriptor will get re-used if there's still data left in a request to transfer. See the ++ * iproc_dma_data_rm_done() and iproc_dma_data_add_ready() routines. ++ */ ++ /** @todo Put these in endpoint context?? */ ++ for (idx = 0; idx < IPROC_EP_DMA_DESC_CNT; idx++) { ++ ep->dma.vir_addr->desc[idx].status = cpu_to_le32(IPROC_USBD_REG_DMA_STAT_BUF_HOST_BUSY); ++ wmb(); ++ ep->dma.vir_addr->desc[idx].next_addr = cpu_to_le32((uint)&ep->dma.phy_addr->desc[idx+1]); ++ } ++ ep->dma.vir_addr->desc[(IPROC_EP_DMA_DESC_CNT - 1)].next_addr = cpu_to_le32((uint)&ep->dma.phy_addr->desc[0]); ++ ++ /* ++ * To simplify things, register the descriptor chain in both directions. Control endpoints are the ++ * only type that will be transferring in both directions, but they will only be transferring in one ++ * direction at a time, so should not be any issues with using the same descriptor set for both directions. ++ * For single direction endpoints, the other direction will not be used. ++ */ ++ ++ iproc_usbd_ep_dma_desc_addr_set(udc->usbd_regs, ep->num, USB_DIR_OUT, &ep->dma.phy_addr->desc[0]); ++ iproc_usbd_ep_dma_desc_addr_set(udc->usbd_regs, ep->num, USB_DIR_IN, &ep->dma.phy_addr->desc[0]); ++} ++ ++/**************************************************************************** ++ * DMA data routines. ++ * ++ * A gadget usb_request buf is used for the data. The entire buf contents may ++ * or may not fit into the descriptor chain at once. When the DMA transfer ++ * associated with a descriptor completes, the descriptor is re-used to add ++ * more segments of the usb_request to the chain as necessary. ++ * ++ * iproc_dma_data_init - Initialization in preparation for DMA of usb_request. ++ * iproc_dma_data_add_ready - Adds usb_request segments into DMA chain until full or no segments left ++ * iproc_dma_data_rm_done - Removes usb_request segments from DMA chain that have completed transfer ++ * iproc_dma_data_finish - Final stage of DMA of the usb_request ++ * ++ ***************************************************************************/ ++static void iproc_dma_data_init(struct iproc_ep *ep) ++{ ++ struct iproc_ep_req *req; ++ struct iproc_udc *udc = ep->udc; ++ ++ req = list_first_entry(&ep->list_queue, struct iproc_ep_req, list_node); ++ ++ if (req->dma_aligned) { ++ /* ++ * This buffer needs to be aligned in order to DMA. We do this by copying into a special buffer we ++ * have for this purpose. Save the original DMA physical address so it can be restored later. ++ * This may not be used, but we'll do it anyways. Then set the DMA address to the aligned buffer ++ * address. Only the DMA physical address is used for the transfers, so the original buffer virtual ++ * address does not need to be changed. Then copy the data into the aligned buffer. ++ */ ++ /** @todo Really only need to do the memcpy for IN data */ ++ ++ req->orig_dma_addr = req->usb_req.dma; ++ req->usb_req.dma = ep->dma.align_addr; ++ memcpy(ep->dma.align_buff, req->usb_req.buf, req->usb_req.length); ++ } ++ ++ ep->dma.done = 0; ++ ep->dma.done_len = 0; ++ ep->dma.todo_len = ep->dma.usb_req->length; ++ ep->dma.buf_addr = ep->dma.usb_req->dma; ++ ep->dma.status = IPROC_USBD_REG_DMA_STAT_RX_SUCCESS; ++ ++ if ((ep->dir == USB_DIR_IN) && (ep->type != USB_ENDPOINT_XFER_ISOC)) { ++ /* ++ * For IN transfers, do not need to segment the buffer into max packet portions ++ * for the DMA descriptors. The hardware will automatically segment into max ++ * packet sizes as necessary. ++ */ ++ ep->dma.max_buf_len = ep->usb_ep.maxpacket; ++ ++ /* ++ * If the request is of zero length, then force the zero flag so iproc_dma_data_add_ready() ++ * will queue the request. Conversely, if the gadget has set the zero flag, leave ++ * it set only if it is needed (request length is a multiple of maxpacket) ++ */ ++ if (ep->dma.usb_req->length == 0) { ++ ep->dma.usb_req->zero = 1; ++ } else if (ep->dma.usb_req->zero) { ++ ep->dma.usb_req->zero = (ep->dma.usb_req->length % ep->usb_ep.maxpacket) ? 0 : 1; ++ } ++ } else { ++ ep->dma.max_buf_len = ep->usb_ep.maxpacket; ++ } ++ ++ dma_desc_chain_reset(ep); ++ ++ iproc_usbd_ep_irq_en(udc->usbd_regs, ep->num, ep->dir); ++} ++ ++static void iproc_dma_data_finish(struct iproc_ep *ep) ++{ ++ struct iproc_ep_req *req; ++ struct iproc_udc *udc = ep->udc; ++ ++ iproc_usbd_ep_irq_dis(udc->usbd_regs, ep->num, ep->dir); ++ iproc_usbd_ep_dma_dis(udc->usbd_regs, ep->num, ep->dir); ++ ++ req = list_first_entry(&ep->list_queue, struct iproc_ep_req, list_node); ++ ++ if (req->dma_aligned) { ++ /* ++ * The original request buffer was not aligned properly, so a special buffer was used ++ * for the transfer. Copy the aligned buffer contents into the original. Also restore ++ * the original dma physical address. ++ */ ++ /** @todo Really only need to do the memcpy for OUT setup/data */ ++ memcpy(req->usb_req.buf, ep->dma.align_buff, req->usb_req.length); ++ req->usb_req.dma = req->orig_dma_addr; ++ } ++} ++ ++static void iproc_dma_data_add_ready(struct iproc_ep *ep) ++{ ++ struct iproc_udc *udc = ep->udc; ++ volatile struct iproc_udc_dma_desc *dma_desc = NULL; ++ uint status; ++ uint len; ++ int enable_dma = 0; ++ ++ /* ++ * DMA must be disabled while this loop is running, as multi-descriptor transfers ++ * will have the descriptor chain in an intermediate state until the last descriptor ++ * is written and the chain terminated. ++ */ ++ if (iproc_usbd_dma_status(udc->usbd_regs)) { ++ enable_dma = 1; ++ iproc_usbd_dma_dis(udc->usbd_regs); ++ } ++ ++ if (!ep->dma.todo_len) { ++ ep->dma.usb_req->zero = 1; ++ } ++ ++ /* ++ * Will only have one request in the chain at a time. Add request segments to the ++ * chain until all parts of the request have been put in the chain or the chain ++ * has no more room. ++ */ ++ while (!dma_desc_chain_full(ep) && (ep->dma.todo_len || ep->dma.usb_req->zero)) { ++ /* ++ * Get the next descriptor in the chain, and then fill the descriptor contents as needed. ++ * Do not set the descriptor buffer status to ready until last to ensure there's no ++ * contention with the hardware. ++ */ ++ dma_desc = dma_desc_chain_alloc(ep); ++ ++ len = ep->dma.todo_len < ep->dma.max_buf_len ? ep->dma.todo_len : ep->dma.max_buf_len; ++ ep->dma.todo_len -= len; ++ ++ status = 0; ++ ++ if (len < ep->dma.max_buf_len) { ++ /* ++ * If this segment is less than the max, then it is the last segment. There's no need to ++ * send a closing ZLP, although this segment might be a ZLP. Regardless, clear the ZLP flag ++ * to ensure that the processing of this request finishes. Also set the end of the descriptor ++ * chain. ++ */ ++ ep->dma.usb_req->zero = 0; ++ status |= IPROC_USBD_REG_DMA_STAT_LAST_DESC; ++ } else if ((ep->dma.todo_len == 0) && !ep->dma.usb_req->zero) { ++ /* ++ * Segment is of the max packet length. Since there's nothing left, it has to also be the last ++ * last segment. No closing ZLP segment requested, just set the end of the descriptor chain. ++ */ ++ status |= IPROC_USBD_REG_DMA_STAT_LAST_DESC; ++ } ++ ++ if ((ep->dir == USB_DIR_IN) && (ep->type == USB_ENDPOINT_XFER_ISOC)) { ++ /* ++ * Increment the frame number for transmit, then use it for the next packet. The frame number ++ * may get larger than its 13-bit size, but the mask will handle the wrap-around so we don't ++ * need to add checks for this condition. E.g. 0x7ff + 1 = 0x800. 0x800 & 0x7ff = 0 which ++ * is the next number in the sequence. ++ */ ++ /** @todo Handle ISOC PIDs and frame numbers used with HS high bandwidth transfers */ ++ /** @todo Might not need to set the last descriptor status. Currently restricting ++ * IN ISOC transfers to the max packet size. ++ */ ++ status |= IPROC_USBD_REG_DMA_STAT_LAST_DESC; ++ ++ ep->dma.frame_num += ep->dma.frame_incr; ++ status |= ((ep->dma.frame_num << IPROC_USBD_REG_DMA_STAT_FRAME_NUM_SHIFT) & IPROC_USBD_REG_DMA_STAT_FRAME_NUM_MASK); ++ } ++ ++ IPROC_USBD_WRITE(dma_desc->buf_addr, ep->dma.buf_addr); ++ status |= (len << IPROC_USBD_REG_DMA_STAT_BYTE_CNT_SHIFT); ++ IPROC_USBD_WRITE(dma_desc->status, status | IPROC_USBD_REG_DMA_STAT_BUF_HOST_READY); ++ wmb(); ++ ep->dma.buf_addr += len; ++ ++ if ((ep->dir == USB_DIR_IN) && (ep->type == USB_ENDPOINT_XFER_ISOC)) { ++ /* With ISOC transfers, only enable one DMA descriptors at a time. ++ */ ++ /** @todo Determine if FIFO will overflow. If it does not, then can remove this check. ++ * This may not even be an issue if the buffer size is restricted to the max packet size ++ * when a request is submitted to the endpoint. ++ */ ++ break; ++ } ++ } ++ /* Set LAST bit on last descriptor we've configured */ ++ if (dma_desc) { ++ IPROC_USBD_BITS_SET(dma_desc->status, IPROC_USBD_REG_DMA_STAT_LAST_DESC); ++ } ++ ++ if (enable_dma) { ++ iproc_usbd_dma_en(udc->usbd_regs); ++ } ++} ++ ++static void iproc_dma_data_rm_done(struct iproc_ep *ep) ++{ ++ struct iproc_udc *udc = ep->udc; ++ volatile struct iproc_udc_dma_desc *dma_desc; ++ uint status; ++ uint len; ++ ++ /* ++ * Will only have one request in the chain at a time. Remove any completed ++ * request segments from the chain so any segments awaiting transfer can ++ * be put in the chain. ++ */ ++ while (!dma_desc_chain_empty(ep)) { ++ /* ++ * Examine the first entry in the chain. If its status is not done, then there's ++ * nothing to remove. ++ */ ++ dma_desc = dma_desc_chain_head(ep); ++ ++ if ((IPROC_USBD_READ(dma_desc->status) & IPROC_USBD_REG_DMA_STAT_BUF_MASK) != IPROC_USBD_REG_DMA_STAT_BUF_DMA_DONE) { ++ break; ++ } ++ ++ /* ++ * The transfer of this request segment has completed. Save the status info and then ++ * take ownership of the descriptor. It is simpler to do this than modifying parts of ++ * the descriptor in order to take ownership. Don't put the descriptor back in the chain ++ * until all info affected by the status has been updated, just to be safe. ++ */ ++ status = IPROC_USBD_READ(dma_desc->status); ++ IPROC_USBD_WRITE(dma_desc->status, IPROC_USBD_REG_DMA_STAT_BUF_HOST_BUSY); ++ wmb(); ++ ++ len = (status & IPROC_USBD_REG_DMA_STAT_NON_ISO_BYTE_CNT_MASK) >> IPROC_USBD_REG_DMA_STAT_NON_ISO_BYTE_CNT_SHIFT; ++ ++ /* RX: For multiple descriptors, len is cumulative, not absolute. ++ * RX: So only adjust the dma fields when we get to the last descriptor ++ * TX: Each descriptor entry is absolute, count them all ++ */ ++ if ((ep->dir == USB_DIR_IN) || (status & IPROC_USBD_REG_DMA_STAT_LAST_DESC)) { ++ ep->dma.done_len += len; ++ ep->dma.usb_req->actual += len; ++ } ++ ++ if ((status & IPROC_USBD_REG_DMA_STAT_RX_MASK) != IPROC_USBD_REG_DMA_STAT_RX_SUCCESS) { ++ ep->dma.status = status & IPROC_USBD_REG_DMA_STAT_RX_MASK; ++ ep->dma.usb_req->status = -EIO; ++ dev_warn(udc->dev, "%s: DMA error: desc=0x%p status=0x%x len=%d add=0x%x remove=0x%x\n", ++ ep->usb_ep.name, dma_desc, status, len, ep->dma.add_idx, ep->dma.rm_idx); ++ } ++ ++ if ((ep->dir == USB_DIR_IN) && (ep->type == USB_ENDPOINT_XFER_ISOC)){ ++ /** @todo Determine if this special processing needs to be done. May not to do this if the ++ * buffer size is restricted to the max packet size when a request is submitted to the endpoint. ++ */ ++ if (ep->dma.usb_req->actual == ep->dma.usb_req->length) { ++ ep->dma.usb_req->status = ENOERROR; ++ } ++ dma_desc_chain_reset(ep); ++ } else { ++ dma_desc_chain_free(ep); ++ } ++ } ++ ++ /* When last segment processed, update status if there has not been an error */ ++ if (!ep->dma.todo_len && (ep->dma.usb_req->status == -EINPROGRESS)) { ++ ep->dma.usb_req->status = ENOERROR; ++ } ++} ++ ++/*************************************************************************** ++ * UDC Operations routines. ++ * iproc_udc_ops_init - Initialization of the UDC in preparation for use by Gadget driver. ++ * iproc_udc_ops_start - Start UDC operations. Happens after a Gadget driver attaches. ++ * iproc_udc_ops_stop - Stop UDC operations. Happens after a Gadget driver detaches. ++ * iproc_udc_ops_finish - Finish / terminate all UDC operations ++ ***************************************************************************/ ++static void iproc_udc_ops_finish(struct iproc_udc *udc) ++{ ++ /* do nothing */ ++ return; ++} ++ ++static void iproc_udc_ops_init(struct iproc_udc *udc) ++{ ++ int idx; ++ struct iproc_ep *ep; ++ ++ iproc_usbd_ops_init(udc->usbd_regs); ++ ++ /* ++ * See usb/gadget/epautoconf.c for endpoint naming conventions. ++ * Control endpoints are bi-directional, but initial transfer (SETUP stage) is always OUT. ++ */ ++ /** @todo Really should make the non endpoint 0 init attributes configurable by the chip specific part ++ * of the driver, idx.e. the device instantiation. The settings below are for a chip specific DWG UDC ++ * core configuration. Also should incorporate the DWG UDC endpoint type attribute as part of this, ++ * which can be control, IN, OUT, or bidirectional. ++ */ ++ INIT_LIST_HEAD(&udc->gadget.ep_list); ++ for (idx = 0; idx < IPROC_UDC_EP_CNT; idx++) { ++ ep = &udc->ep[idx]; ++ ++ ep->udc = udc; ++ ep->num = idx; ++ ++ ep->dir = (xgs_iproc_ep_info[idx].caps.dir_in) ? USB_DIR_IN : USB_DIR_OUT;; ++ ep->beq_addr = idx | ep->dir; ++ ep->stopped = 0; ++ ep->type = xgs_iproc_ep_info[idx].type; ++ ++ ep->usb_ep.name = xgs_iproc_ep_info[idx].name; ++ ep->usb_ep.caps = xgs_iproc_ep_info[idx].caps; ++ ep->usb_ep.ops = &xgs_iproc_udc_ep_ops; ++ list_add_tail(&ep->usb_ep.ep_list, &udc->gadget.ep_list); ++ usb_ep_set_maxpacket_limit(&ep->usb_ep, xgs_iproc_ep_info[idx].msize); ++ ep->usb_ep.desc = NULL; ++ INIT_LIST_HEAD(&ep->list_queue); ++ ++ iproc_usbd_ep_ops_init(udc->usbd_regs, ep->num, ep->type, ep->dir, xgs_iproc_ep_info[idx].msize); ++ ++ iproc_dma_ep_init(ep); ++ } ++ ++ udc->gadget.ep0 = &udc->ep[0].usb_ep; ++ list_del(&udc->ep[0].usb_ep.ep_list); ++ ++ iproc_usbd_self_pwr_en(udc->usbd_regs); ++} ++ ++static void iproc_udc_ops_start(struct iproc_udc *udc) ++{ ++ int idx; ++ ++ /* ++ * Just enable interrupts for now. Endpoint 0 will get enabled once the speed enumeration ++ * has completed. The Device DMA enable is global in scope. There's endpoint specific ++ * DMA enables that will happen later. ++ */ ++ iproc_usbd_irq_en(udc->usbd_regs, (IPROC_USBD_IRQ_SPEED_ENUM_DONE | ++ IPROC_USBD_IRQ_BUS_SUSPEND | ++ IPROC_USBD_IRQ_BUS_IDLE | ++ IPROC_USBD_IRQ_BUS_RESET | ++ IPROC_USBD_IRQ_SET_INTF | ++ IPROC_USBD_IRQ_SET_CFG)); ++ iproc_usbd_dma_en(udc->usbd_regs); ++ ++ /* Enable interrupts for all configured endpoints */ ++ for (idx = 0; idx < IPROC_UDC_EP_CNT; ++idx) { ++ if (udc->ep[idx].usb_ep.name) { ++ iproc_usbd_ep_irq_en(udc->usbd_regs, udc->ep[idx].num, USB_DIR_OUT); ++ iproc_usbd_ep_irq_en(udc->usbd_regs, udc->ep[idx].num, USB_DIR_IN); ++ } ++ } ++ iproc_usbd_nak_response_dis(udc->usbd_regs); ++} ++ ++static void iproc_udc_ops_stop(struct iproc_udc *udc) ++{ ++ struct iproc_ep *ep; ++ ++ iproc_usbd_dma_dis(udc->usbd_regs); ++ iproc_usbd_irq_dis(udc->usbd_regs, IPROC_USBD_IRQ_ALL); ++ iproc_usbd_irq_clear(udc->usbd_regs, IPROC_USBD_IRQ_ALL); ++ ++ udc->gadget.speed = USB_SPEED_UNKNOWN; ++ ++ iproc_udc_req_queue_flush(&udc->ep[0], -ESHUTDOWN); ++ list_for_each_entry(ep, &udc->gadget.ep_list, usb_ep.ep_list) { ++ iproc_udc_req_queue_flush(ep, -ESHUTDOWN); ++ } ++} ++ ++static void iproc_udc_ops_disconnect(struct iproc_udc *udc) ++{ ++ struct iproc_ep *ep; ++ int idx; ++ ++ for (idx = 0; idx < IPROC_UDC_EP_CNT; idx++) { ++ ep = &udc->ep[idx]; ++ ++ if (ep->dma.usb_req) { ++ /* Flush DMA, reqeust still pending */ ++ iproc_usbd_ep_fifo_flush_en(udc->usbd_regs, 0, IPROC_USBD_EP_DIR_IN); ++ iproc_usbd_ep_fifo_flush_dis(udc->usbd_regs, 0, IPROC_USBD_EP_DIR_IN); ++ ++ iproc_udc_req_xfer_process(ep); ++ } ++ } ++} ++ ++static void iproc_udc_ops_shutdown(struct iproc_udc *udc) ++{ ++ struct iproc_ep *ep; ++ ++ udc->ep[0].desc = NULL; ++ list_for_each_entry(ep, &udc->gadget.ep_list, usb_ep.ep_list) { ++ ep->desc = NULL; ++ } ++ ++ udc->gadget.dev.driver = NULL; ++ udc->gadget_driver = NULL; ++} ++ ++ ++/**************************************************************************** ++ * Control Endpoint SETUP related routines. ++ * ++ * iproc_ep_setup_init - Prepares for next SETUP Rx. Status indicates if STALL req'd. ++ * iproc_ep_setup_process - Handle Rx of a SETUP. ++ ***************************************************************************/ ++static void iproc_ep_setup_init(struct iproc_ep *ep, int status) ++{ ++ struct iproc_udc *udc = ep->udc; ++ ++ /* Re-enable transfers to the SETUP buffer, clear IN and OUT NAKs, and re-enable OUT interrupts. */ ++ ep->dma.vir_addr->setup.status = cpu_to_le32(IPROC_USBD_REG_DMA_STAT_BUF_HOST_READY); ++ ep->dir = USB_DIR_OUT; ++ ep->stopped = 0; ++ ++ if (status == ENOERROR) { ++ /* Handling of previous SETUP was OK. Just clear any NAKs. */ ++ ++ iproc_usbd_ep_nak_clear(udc->usbd_regs, ep->num, USB_DIR_OUT); ++ iproc_usbd_ep_nak_clear(udc->usbd_regs, ep->num, USB_DIR_IN); ++ } else { ++ /* ++ * Handling of previous SETUP failed. Set the STALL. This will get cleared ++ * when the next SETUP is rx'd. ++ */ ++ iproc_usbd_ep_stall_en(udc->usbd_regs, ep->num, USB_DIR_IN); ++ iproc_usbd_ep_stall_en(udc->usbd_regs, ep->num, USB_DIR_OUT); ++ } ++ ++ iproc_usbd_ep_irq_en(udc->usbd_regs, ep->num, USB_DIR_OUT); ++ iproc_usbd_ep_dma_en(udc->usbd_regs, ep->num, USB_DIR_OUT); ++} ++ ++void iproc_ep_setup_process(struct iproc_ep *ep, struct usb_ctrlrequest *setup) ++{ ++ struct iproc_udc *udc = ep->udc; ++ uint value; ++ uint index; ++ uint length; ++ int status; ++ ++ value = le16_to_cpu(setup->wValue); ++ index = le16_to_cpu(setup->wIndex); ++ length = le16_to_cpu(setup->wLength); ++ ++ /* ++ * Any SETUP packets appearing here need to be handled by the gadget driver. Some SETUPs may have ++ * already been silently handled and acknowledged by the DWC UDC. The exceptions to this rule are the ++ * USB_REQ_SET_CONFIGURATION and USB_REQ_SET_INTERFACE, which have been only partially handled with ++ * the expectation that some additional software processing is required in order to complete these requests. ++ * Thus, they have not been acknowledged by the DWC UDC. There is no DATA stage for these requests. ++ */ ++ ++ /* ++ * Set the direction of the subsequent DATA stage of a control transfer. This is an ++ * optional stage. It may not exist for all control transfers. If there is a DATA ++ * stage, this info is used for DMA operations for any requests received from the ++ * Gadget driver. ++ */ ++ ++ ep->dir = setup->bRequestType & USB_ENDPOINT_DIR_MASK; ++ ++ if (ep->num != 0) { ++ /** @todo Make changes here if the Linux USB gadget ever supports a control endpoint other ++ * than endpoint 0. The DWC UDC supports multiple control endpoints, and this driver has ++ * been written with this in mind. To make things work, really need to change the Gadget ++ * setup() callback parameters to provide an endpoint context, or add something similar ++ * to the usb_ep structure, or possibly use a usb_request to hold a setup data packet. ++ */ ++ ++ dev_err(udc->dev, "%s: control transfer not supported\n", ep->usb_ep.name); ++ status = -EOPNOTSUPP; ++ } else { ++ /* ++ * Forward the SETUP to the gadget driver for processing. The appropriate directional ++ * interrupt and NAK clear will happen when the DATA stage request is queued. ++ */ ++ spin_unlock(&udc->lock); ++ status = udc->gadget_driver->setup(&udc->gadget, setup); ++ spin_lock(&udc->lock); ++ } ++ ++ if (status < 0) { ++ /* ++ * Error occurred during the processing of the SETUP, so enable STALL. This condition ++ * can only be cleared with the RX of another SETUP, so prepare for that event. ++ */ ++ dev_err(udc->dev, "%s: SETUP %02x.%02x STALL; status=%d\n", ++ ep->usb_ep.name, setup->bRequestType, setup->bRequest, status); ++ ++ iproc_ep_setup_init(ep, status); ++ } else if (length == 0) { ++ /* No DATA stage. Just need to prepare for the next SETUP. */ ++ iproc_ep_setup_init(ep, ENOERROR); ++ } else { ++ /* ++ * The SETUP stage processing has completed OK, and there may or may not be a request queued ++ * for the DATA stage. When the DATA stage completes, preparation for the RX of the next ++ * SETUP will be done. ++ */ ++ } ++} ++ ++ ++/**************************************************************************** ++ * IRQ routines. ++ * ++ * xgs_iproc_udc_isr - top level entry point. ++ * iproc_cfg_isr - device (endpoint 0) set config interrupt handler ++ * iproc_inf_isr - device (endpoint 0) set interface interrupt handler ++ * iproc_speed_isr - device speed enumeration done interrupt handler ++ * iproc_ep_in_isr - top level IN endpoint related interrupt handler ++ * iproc_ep_out_isr - top level OUT endpoint related interrupt handler ++ * iproc_ep_out_setup_isr - Control endpoint SETUP Rx handler. This may get ++ * called directly as the result of an endpoint OUT interrupt, or ++ * indirectly as the result of device SET_CFG or SET_INTF. ++ ***************************************************************************/ ++static void iproc_cfg_isr(struct iproc_udc *udc) ++{ ++ struct usb_ctrlrequest setup; ++ int idx; ++ u16 cfg; ++ ++ /* ++ * Device Configuration SETUP has been received. This is not placed in the SETUP ++ * DMA buffer. The packet has to be re-created here so it can be forwarded to the ++ * gadget driver to act upon. ++ */ ++ ++ cfg = (u16) iproc_usbd_cfg_num(udc->usbd_regs); ++ ++ setup.bRequestType = USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE; ++ setup.bRequest = USB_REQ_SET_CONFIGURATION; ++ setup.wValue = cpu_to_le16(cfg); ++ setup.wIndex = 0; ++ setup.wLength = 0; ++ ++ /* ++ * Setting the configuration number before the gadget responds is a bit presumptious, but should ++ * not be fatal. ++ */ ++ /** @todo Do not set endpoint 0? Or is it a don't care? */ ++ for (idx = 0; idx < IPROC_UDC_EP_CNT; idx++) { ++ iproc_usbd_ep_cfg_set(udc->usbd_regs, idx, cfg); ++ } ++ ++ printk(KERN_INFO "SET CFG=%d\n", cfg); ++ ++ iproc_ep_setup_process(&udc->ep[0], &setup); ++ iproc_usbd_setup_done(udc->usbd_regs); ++} ++ ++static void iproc_inf_isr(struct iproc_udc *udc) ++{ ++ struct usb_ctrlrequest setup; ++ uint idx; ++ u16 intf; ++ u16 alt; ++ ++ /* ++ * Device Interface SETUP has been received. This is not placed in the SETUP ++ * DMA buffer. The packet has to be re-created here so it can be forwarded to the ++ * gadget driver to act upon. ++ */ ++ intf = (u16)iproc_usbd_intf_num(udc->usbd_regs); ++ alt = (u16)iproc_usbd_alt_num(udc->usbd_regs); ++ ++ setup.bRequestType = USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_INTERFACE; ++ setup.bRequest = USB_REQ_SET_INTERFACE; ++ setup.wValue = cpu_to_le16(alt); ++ setup.wIndex = cpu_to_le16(intf); ++ setup.wLength = 0; ++ ++ /* ++ * Setting the interface numbers before the gadget responds is a bit presumptious, but should ++ * not be fatal. ++ */ ++ for (idx = 0; idx < IPROC_UDC_EP_CNT; idx++) { ++ iproc_usbd_ep_alt_set(udc->usbd_regs, idx, alt); ++ iproc_usbd_ep_intf_set(udc->usbd_regs, idx, intf); ++ } ++ ++ iproc_ep_setup_process(&udc->ep[0], &setup); ++ iproc_usbd_setup_done(udc->usbd_regs); ++} ++ ++static void iproc_speed_isr(struct iproc_udc *udc) ++{ ++ uint speed; ++ ++ speed = udc->gadget.speed; ++ ++ switch(iproc_usbd_speed_get(udc->usbd_regs)) { ++ case IPROC_USBD_SPEED_HIGH: ++ printk(KERN_INFO "HIGH SPEED\n"); ++ udc->gadget.speed = USB_SPEED_HIGH; ++ break; ++ case IPROC_USBD_SPEED_FULL: ++ printk(KERN_INFO "FULL SPEED\n"); ++ udc->gadget.speed = USB_SPEED_FULL; ++ break; ++ case IPROC_USBD_SPEED_LOW: ++ dev_warn(udc->dev, "low speed not supported\n"); ++ udc->gadget.speed = USB_SPEED_LOW; ++ break; ++ default: ++ dev_err(udc->dev, "unknown speed=0x%x\n", iproc_usbd_speed_get(udc->usbd_regs)); ++ break; ++ } ++ ++ if ((speed == USB_SPEED_UNKNOWN) && (udc->gadget.speed != USB_SPEED_UNKNOWN)) { ++ /* ++ * Speed has not been enumerated before, so now we can initialize transfers on endpoint 0. ++ * Also have to disable the NAKs at a global level, which has been in place while waiting ++ * for enumeration to complete. ++ */ ++ iproc_ep_setup_init(&udc->ep[0], ENOERROR); ++ iproc_usbd_nak_response_dis(udc->usbd_regs); ++ } ++} ++ ++static void iproc_ep_in_isr(struct iproc_ep *ep) ++{ ++ struct iproc_udc *udc = ep->udc; ++ uint status; ++ ++ status = iproc_usbd_ep_stat_active(udc->usbd_regs, ep->num, USB_DIR_IN); ++ iproc_usbd_ep_stat_clear(udc->usbd_regs, ep->num, USB_DIR_IN, status); ++ ++ if (!status) { ++ return; ++ } ++ ++ /** @todo check might only be for direction... */ ++ if ((ep->dir != USB_DIR_IN) && (ep->type != USB_ENDPOINT_XFER_CONTROL)) { ++ dev_err(udc->dev, "%s: unexpected IN interrupt\n", ep->usb_ep.name); ++ return; ++ } ++ ++ if (ep->dir != USB_DIR_IN) { ++ /* This probably should not be happening */ ++ dev_warn(udc->dev, "%s: CTRL dir OUT\n", ep->usb_ep.name); ++ } ++ ++ if ((ep->type == USB_ENDPOINT_XFER_ISOC) && ++ (status & (IPROC_USBD_EP_STAT_IN_XFER_DONE | IPROC_USBD_EP_STAT_DMA_BUF_UNAVAIL))) { ++ dev_warn(udc->dev, "%s: ISOC IN unexpected status=0x%x\n", ep->usb_ep.name, status); ++ } ++ ++ if (status & IPROC_USBD_EP_STAT_IN_TOKEN_RX) { ++ /* ++ * If there's any IN requests, the DMA should be setup and ready to go if ++ * the endpoint is not an ISOC. Nothing to do in this case. However, if ++ * this is an ISOC endpoint, then this interrupt implies there was no ++ * data available for this frame number. This will happen if the gadget ++ * does not have any data queued to send in this frame, or we have been ++ * waiting for this event to occur so we can get alignment with the host ++ * for the interval. This alignment is necessary when the interval is ++ * greater than one frame / uframe. E.g. for an audio stream sending ++ * samples @ 5ms intervals on a FS link, this corresponds to a period ++ * of 5 frames. Samples with be queued for every 5th frame number after ++ * the frame number in which this interrupt occurred. ++ */ ++ status &= ~IPROC_USBD_EP_STAT_IN_TOKEN_RX; ++ iproc_usbd_ep_nak_clear(udc->usbd_regs, ep->num, USB_DIR_IN); ++ ++ if ((ep->type == USB_ENDPOINT_XFER_ISOC)) { ++ /* Always align to the current frame number for subsequent transfers. */ ++ ep->dma.frame_num = iproc_usbd_last_rx_frame_num(udc->usbd_regs); ++ if (ep->dma.usb_req != NULL) { ++ /* ++ * Might have something queued when waiting for alignment. If something is queued, ++ * it is already too late for the current transfer point. It will also have been ++ * placed in the queue at some point before this interrupt, and it will be stale ++ * if we try to transmit at the next transfer point. ++ */ ++ ep->dma.usb_req->status = -EREMOTEIO; ++ iproc_udc_req_xfer_process(ep); ++ } ++ } ++ } ++ ++ if (status & IPROC_USBD_EP_STAT_IN_DMA_DONE) { ++ /* ++ * DMA has completed, but cannot start next transfer until IPROC_USBD_EP_STAT_IN_XFER_DONE. ++ * To avoid race conditions and other issues, do not release the current transfer until both ++ * interrupts have arrived. Normally this interrupt will arrive at or before the IN_XFER_DONE, ++ * but there have been situations when the system is under load that this interrupt might ++ * arrive after the IN_XFER_DONE, in which case we will need to do the processing now. ++ * The exception to this rule is for ISOC endpoints. They will only get this interrupt to ++ * indicate that DMA has completed. ++ */ ++ status &= ~IPROC_USBD_EP_STAT_IN_DMA_DONE; ++ ++ if ((ep->type == USB_ENDPOINT_XFER_ISOC)) { ++ iproc_udc_req_xfer_process(ep); ++ } else if (ep->dma.done & IPROC_USBD_EP_STAT_IN_XFER_DONE) { ++ /* ++ * Did not receive the IN_DMA_DONE interrupt for this request before or ++ * at the same time as the IN_XFER_DONE interrupt, so the request ++ * processing was postponed until the IN_DMA_DONE interrupt arrived. ++ * See handling of IN_XFER_DONE status below. ++ */ ++ iproc_udc_req_xfer_process(ep); ++ } else { ++ /* ++ * IN_DMA_DONE received. Save this info so request processing will be ++ * done when the IN_XFER_DONE interrupt is received. This may happen ++ * immediately, idx.e. both IN_DMA_DONE and IN_XFER_DONE status are ++ * set when the interrupt processing takes place. ++ */ ++ ep->dma.done = IPROC_USBD_EP_STAT_IN_DMA_DONE; ++ } ++ } ++ ++ if (status & IPROC_USBD_EP_STAT_IN_XFER_DONE) { ++ status &= ~(IPROC_USBD_EP_STAT_IN_XFER_DONE); ++ status &= ~(IPROC_USBD_EP_STAT_IN_FIFO_EMPTY); ++ ++ if (ep->dma.done & IPROC_USBD_EP_STAT_IN_DMA_DONE) { ++ /* ++ * Have received both the IN_DMA_DONE and IN_XFER_DONE interrupts ++ * for this request. OK to process the request (remove the request ++ * and start the next one). ++ */ ++ iproc_udc_req_xfer_process(ep); ++ } else { ++ /* ++ * Have not received the IN_DMA_DONE interrupt for this request. ++ * Need to postpone processing of the request until the IN_DMA_DONE ++ * interrupt occurs. See handling of IN_DMA_DONE status above. ++ */ ++ ep->dma.done = IPROC_USBD_EP_STAT_IN_XFER_DONE; ++ } ++ } ++ ++ /* Clear the FIFO EMPTY bit, not to print error message */ ++ status &= ~(IPROC_USBD_EP_STAT_IN_FIFO_EMPTY); ++ ++ if (status & IPROC_USBD_EP_STAT_DMA_BUF_UNAVAIL) { ++ dev_err(udc->dev, "%s: DMA BUF NOT AVAIL\n", ep->usb_ep.name); ++ status &= ~(IPROC_USBD_EP_STAT_DMA_BUF_UNAVAIL); ++ iproc_udc_req_xfer_process(ep); ++ } ++ ++ if (status & IPROC_USBD_EP_STAT_DMA_ERROR) { ++ status &= ~IPROC_USBD_EP_STAT_DMA_ERROR; ++ dev_err(udc->dev, "%s: DMA ERROR\n", ep->usb_ep.name); ++ iproc_udc_req_xfer_error(ep, -EIO); ++ } ++ ++ if (status) { ++ dev_err(udc->dev, "exit: %s %s: unknown status=0x%x\n", __func__, ep->usb_ep.name, status); ++ } ++} ++ ++static void iproc_ep_out_setup_isr(struct iproc_ep *ep) ++{ ++ struct iproc_udc *udc = ep->udc; ++ struct iproc_udc_dma_setup *dma; ++ ++ dma = &ep->dma.vir_addr->setup; ++ if ((IPROC_USBD_READ(dma->status) & IPROC_USBD_REG_DMA_STAT_BUF_MASK) != IPROC_USBD_REG_DMA_STAT_BUF_DMA_DONE) { ++ dev_err(udc->dev, "%s: unexpected DMA buf status=0x%x\n", ep->usb_ep.name, (IPROC_USBD_READ(dma->status) & IPROC_USBD_REG_DMA_STAT_BUF_MASK)); ++ iproc_ep_setup_init(ep, ENOERROR); ++ } else if ((IPROC_USBD_READ(dma->status) & IPROC_USBD_REG_DMA_STAT_RX_MASK) != IPROC_USBD_REG_DMA_STAT_RX_SUCCESS) { ++ dev_err(udc->dev, "%s: unexpected DMA rx status=0x%x\n", ep->usb_ep.name, (IPROC_USBD_READ(dma->status) & IPROC_USBD_REG_DMA_STAT_RX_MASK)); ++ iproc_ep_setup_init(ep, ENOERROR); ++ } else { ++ if (ep->num != 0) { ++ /** @todo Handle the cfg / intf / alt fields of the DMA status. This will only be any issue ++ * once the Linux Gadget driver framework supports control transfers on an endpoint other ++ * than 0. ++ */ ++ dev_warn(udc->dev, "%s: CTRL xfr support not complete\n", ep->usb_ep.name); ++ } ++ /* ++ * Take ownership of the descriptor while processing the request. Ownership will be released ++ * when ready to Rx SETUP again. ++ */ ++ IPROC_USBD_BITS_MODIFY(dma->status, IPROC_USBD_REG_DMA_STAT_BUF_MASK, IPROC_USBD_REG_DMA_STAT_BUF_HOST_BUSY); ++ iproc_ep_setup_process(ep, (struct usb_ctrlrequest *)&dma->data1); ++ } ++} ++ ++static void iproc_ep_out_isr(struct iproc_ep *ep) ++{ ++ struct iproc_udc *udc = ep->udc; ++ uint status; ++ ++ status = iproc_usbd_ep_stat_active(udc->usbd_regs, ep->num, USB_DIR_OUT); ++ iproc_usbd_ep_stat_clear(udc->usbd_regs, ep->num, USB_DIR_OUT, status); ++ ++ /* ++ * Remove the Rx packet size field from the status. The datasheet states this field is not used ++ * in DMA mode, but that is not true. ++ */ ++ status &= IPROC_USBD_EP_STAT_ALL; ++ ++ if (!status) { ++ return; ++ } ++ ++ if ((ep->dir != USB_DIR_OUT) && (ep->type != USB_ENDPOINT_XFER_CONTROL)) { ++ dev_err(udc->dev, "%s: unexpected OUT interrupt\n", ep->usb_ep.name); ++ return; ++ } ++ ++ if (ep->dir != USB_DIR_OUT) { ++ /* This probably should not be happening */ ++ dev_err(udc->dev, "%s: CTRL dir IN\n", ep->usb_ep.name); ++ } ++ ++ if (status & IPROC_USBD_EP_STAT_OUT_DMA_DATA_DONE) { ++ status &= ~IPROC_USBD_EP_STAT_OUT_DMA_DATA_DONE; ++ iproc_udc_req_xfer_process(ep); ++ } ++ ++ if (status & IPROC_USBD_EP_STAT_OUT_DMA_SETUP_DONE) { ++ status &= ~IPROC_USBD_EP_STAT_OUT_DMA_SETUP_DONE; ++ iproc_ep_out_setup_isr(ep); ++ } ++ ++ if (status & IPROC_USBD_EP_STAT_DMA_BUF_UNAVAIL) { ++ /** @todo Verify under what situations this can happen. Should be when chain has emptied but last desc not reached */ ++ /** @todo status for desc updates */ ++ ++ status &= ~IPROC_USBD_EP_STAT_DMA_BUF_UNAVAIL; ++ dev_err(udc->dev, "%s: DMA BUF NOT AVAIL\n", ep->usb_ep.name); ++ iproc_udc_req_xfer_process(ep); ++ } ++ ++ if (status & IPROC_USBD_EP_STAT_DMA_ERROR) { ++ status &= ~IPROC_USBD_EP_STAT_DMA_ERROR; ++ dev_err(udc->dev, "%s: DMA ERROR\n", ep->usb_ep.name); ++ /** @todo merge XferError and XferProcess?? */ ++ iproc_udc_req_xfer_error(ep, -EIO); ++ } ++ ++ if (status) { ++ dev_err(udc->dev, "%s: unknown status=0x%x\n", ep->usb_ep.name, status); ++ } ++} ++ ++irqreturn_t xgs_iproc_udc_isr(int irq, void *context) ++{ ++ struct iproc_udc *udc = NULL; ++ ulong flags; ++ uint stat, epin_stat, epout_stat; ++ int idx; ++ ++ udc = (struct iproc_udc *)context; ++ ++ spin_lock_irqsave(&udc->lock, flags); ++ ++ if (!udc || !udc->gadget_driver) { ++ dev_err(udc->dev, "Invalid context or no driver registered: irq dev=0x%x\n", iproc_usbd_irq_active(udc->usbd_regs)); ++ ++ iproc_usbd_irq_clear(udc->usbd_regs, IPROC_USBD_IRQ_ALL); ++ iproc_usbd_ep_irq_list_clear(udc->usbd_regs, USB_DIR_IN, ~0); ++ iproc_usbd_ep_irq_list_clear(udc->usbd_regs, USB_DIR_OUT, ~0); ++ ++ spin_unlock_irqrestore(&udc->lock, flags); ++ return IRQ_HANDLED; ++ } ++ ++ stat = iproc_usbd_irq_active(udc->usbd_regs); ++ epin_stat = iproc_usbd_ep_irq_list_active(udc->usbd_regs, USB_DIR_IN); ++ epout_stat = iproc_usbd_ep_irq_list_active(udc->usbd_regs, USB_DIR_OUT); ++ ++ if (!(stat || epin_stat || epout_stat)) { ++ return IRQ_NONE; ++ } ++ ++ iproc_usbd_irq_clear(udc->usbd_regs, stat); ++ iproc_usbd_ep_irq_list_clear(udc->usbd_regs, USB_DIR_IN, epin_stat); ++ iproc_usbd_ep_irq_list_clear(udc->usbd_regs, USB_DIR_OUT, epout_stat); ++ ++ /* ++ * Handle the SET_CFG and SET_INTF interrupts after the endpoint and other device interrupts. ++ * There can be some race conditions where we have an endpoint 0 interrupt pending for the ++ * completion of a previous endpoint 0 transfer (e.g. a GET config) when a SETUP arrives ++ * corresponding to the SET_CFG and SET_INTF. Need to complete the processing of the previous ++ * transfer before handling the next one, idx.e. the SET_CFG or SET_INTF. ++ */ ++ if (stat & IPROC_USBD_IRQ_BUS_RESET) { ++ printk(KERN_INFO "BUS reset\n"); ++ } ++ if (stat & IPROC_USBD_IRQ_BUS_SUSPEND) { ++ dev_dbg(udc->dev, "BUS suspend\n"); ++ } ++ if (stat & IPROC_USBD_IRQ_BUS_IDLE) { ++ dev_dbg(udc->dev, "BUS idle\n"); ++ iproc_udc_ops_disconnect(udc); ++ } ++ if (stat & IPROC_USBD_IRQ_SPEED_ENUM_DONE) { ++ dev_dbg(udc->dev, "BUS speed enum done\n"); ++ iproc_speed_isr(udc); ++ } ++ ++ /* endpoint interrupts handler */ ++ for (idx = 0; idx < IPROC_UDC_EP_CNT; idx++) { ++ if (epin_stat & (1 << idx)) { ++ iproc_ep_in_isr(&udc->ep[idx]); ++ } ++ if (epout_stat & (1 << idx)) { ++ iproc_ep_out_isr(&udc->ep[idx]); ++ } ++ } ++ ++ /* SET_CFG and SET_INTF interrupts handler */ ++ if (stat & IPROC_USBD_IRQ_SET_CFG) { ++ iproc_cfg_isr(udc); ++ } ++ if (stat & IPROC_USBD_IRQ_SET_INTF) { ++ iproc_inf_isr(udc); ++ } ++ ++ spin_unlock_irqrestore(&udc->lock, flags); ++ ++ return IRQ_HANDLED; ++} ++ ++/*************************************************************************** ++* Endpoint request operations ++***************************************************************************/ ++static void iproc_udc_req_queue_flush(struct iproc_ep *ep, int status) ++{ ++ struct iproc_udc *udc = ep->udc; ++ struct iproc_ep_req *req; ++ ++ ep->stopped = 1; ++ iproc_usbd_ep_ops_finish(udc->usbd_regs, ep->num); ++ ++ while (!list_empty(&ep->list_queue)) { ++ req = list_first_entry(&ep->list_queue, struct iproc_ep_req, list_node); ++ iproc_udc_req_xfer_done(ep, req, status); ++ } ++ ep->dma.usb_req = NULL; ++} ++ ++ ++static void iproc_udc_req_xfer_add(struct iproc_ep *ep, struct iproc_ep_req *req) ++{ ++ struct iproc_udc *udc = ep->udc; ++ list_add_tail(&req->list_node, &ep->list_queue); ++ ++ /** @todo Is this necessary?? Stopped happens as a result of a halt, complete(), dequeue(), nuke(). ++ * nuke() is called when ep disabled, during setup processing, and by udc_queisce(). The latter is ++ * called during vbus state change (cable insert/remove), USB reset interrupt, and gadget deregister. ++ */ ++ if (ep->stopped) { ++ return; ++ } ++ ++ if ((ep->dir == USB_DIR_IN) && (ep->type == USB_ENDPOINT_XFER_ISOC) && ep->dma.usb_req && (ep->dma.frame_num == FRAME_NUM_INVALID)) { ++ /* ++ * Gadget has a request already queued, but still have not received an IN token from the host ++ * and the interval window is not aligned. Queued packet is now very stale, so remove it. ++ */ ++ ++ iproc_dma_data_finish(ep); ++ /** @todo Move set of ep->dma.usb_req to iproc_dma_data_init() and iproc_dma_data_finish() routines. */ ++ ep->dma.usb_req = NULL; ++ iproc_udc_req_xfer_done(ep, list_first_entry(&ep->list_queue, struct iproc_ep_req, list_node), -EREMOTEIO); ++ } ++ ++ /** @todo Current transfer is always the queue head. Do we need a separate pointer? Maybe just a pointer to usb_request ++ * need to know if the queue head has already been loaded. Maybe that's the point of the "stopped". ++ */ ++ if (!ep->dma.usb_req) { ++ if ((ep->dir == USB_DIR_IN) && (ep->type == USB_ENDPOINT_XFER_ISOC) && ++ (ep->dma.frame_num == FRAME_NUM_INVALID)) { ++ /* ++ * Delay any ISOC IN DMA operations until it is known what frame number the host ++ * is going to start transfers with. Normally might just return requests until ++ * this event occurs. However, the zero gadget does not submit requests based on ++ * its own timer or similar, so if the request is returned right away things are ++ * going to thrash, as another request will be immediately submitted. ++ */ ++ ep->dma.usb_req = &(list_first_entry(&ep->list_queue, struct iproc_ep_req, list_node))->usb_req; ++ iproc_dma_data_init(ep); ++ iproc_usbd_ep_nak_clear(udc->usbd_regs, ep->num, ep->dir); ++ iproc_usbd_ep_irq_en(udc->usbd_regs, ep->num, ep->dir); ++ } else { ++ req = list_first_entry(&ep->list_queue, struct iproc_ep_req, list_node); ++ ep->dma.usb_req = &req->usb_req; ++ iproc_dma_data_init(ep); ++ iproc_dma_data_add_ready(ep); ++ iproc_usbd_ep_nak_clear(udc->usbd_regs, ep->num, ep->dir); ++ iproc_usbd_ep_dma_en(udc->usbd_regs, ep->num, ep->dir); ++ ++ /* needed for gadget commands to complete correctly - possible locking issue */ ++ mdelay(3); ++ } ++ } ++} ++ ++static void iproc_udc_req_xfer_done(struct iproc_ep *ep, struct iproc_ep_req *req, int status) ++{ ++ struct iproc_udc *udc = ep->udc; ++ uint stopped; ++ ++ list_del_init(&req->list_node); ++ ++ if (req->usb_req.status == -EINPROGRESS) { ++ req->usb_req.status = status; ++ } ++ ++ if (req->dma_aligned) { ++ req->dma_aligned = 0; ++ } else if (req->dma_mapped) { ++ /* ++ * A physical address was not provided for the DMA buffer. Release any resources ++ * that were requested by the driver. ++ */ ++ dma_unmap_single(udc->gadget.dev.parent, req->usb_req.dma, req->usb_req.length, ++ (ep->dir == USB_DIR_IN ? DMA_TO_DEVICE : DMA_FROM_DEVICE)); ++ ++ req->dma_mapped = 0; ++ req->usb_req.dma = DMA_ADDR_INVALID; ++ } ++ ++ /* ++ * Disable DMA operations during completion callback. The callback may cause requests to be ++ * added to the queue, but we don't want to change the state of the queue head. ++ */ ++ stopped = ep->stopped; ++ ep->stopped = 1; ++ spin_unlock(&udc->lock); ++ req->usb_req.complete(&ep->usb_ep, &req->usb_req); ++ spin_lock(&udc->lock); ++ ep->stopped = stopped; ++} ++ ++static void iproc_udc_req_xfer_error(struct iproc_ep *ep, int status) ++{ ++ struct iproc_udc *udc = ep->udc; ++ ++ if (!ep->dma.usb_req) { ++ dev_err(udc->dev, "%s: No request being transferred\n", ep->usb_ep.name); ++ return; ++ } ++ ++ /** @todo abort current DMA, start next transfer if there is one. */ ++ ep->dma.usb_req->status = status; ++ iproc_udc_req_xfer_process(ep); ++} ++ ++static void iproc_udc_req_xfer_process(struct iproc_ep *ep) ++{ ++ struct iproc_udc *udc = ep->udc; ++ struct iproc_ep_req *req; ++ ++ /** @todo Current transfer is always the queue head. Do we need a separate pointer? Maybe just a pointer to usb_request */ ++ if (!ep->dma.usb_req) { ++ dev_err(udc->dev, "%s: No request being transferred\n", ep->usb_ep.name); ++ return; ++ } ++ ++ iproc_usbd_ep_dma_dis(udc->usbd_regs, ep->num, ep->dir); ++ iproc_dma_data_rm_done(ep); ++ ++ if (ep->dma.usb_req->status != -EINPROGRESS) { ++ /* ++ * Current transfer stage has finished. This may or may not be with error. ++ * Complete the transfer as needed before starting the next one, if any. ++ */ ++ iproc_dma_data_finish(ep); ++ ++ if ((ep->type == USB_ENDPOINT_XFER_CONTROL) && (ep->dir == USB_DIR_IN) && (ep->dma.usb_req->status == ENOERROR)) { ++ /* ++ * For the status phase of control IN transfers, the hardware requires that an OUT DMA transfer ++ * actually takes place. This should be just an OUT ZLP, and we will re-use the IN buffer that ++ * just completed transfer for this purpose. There should be no harm in doing this, even if the ++ * OUT status is more than a ZLP. ++ */ ++ ep->dir = USB_DIR_OUT; ++ iproc_dma_data_init(ep); ++ } else { ++ /* ++ * All transfer stages have completed. Return the request to the gadget driver, and then ++ * setup for the next transfer. ++ */ ++ iproc_udc_req_xfer_done(ep, list_first_entry(&ep->list_queue, struct iproc_ep_req, list_node), ENOERROR); ++ ++ if (ep->type == USB_ENDPOINT_XFER_CONTROL) { ++ iproc_ep_setup_init(ep, ENOERROR); ++ } ++ ++ if (list_empty(&ep->list_queue)) { ++ /** @todo Probably should more closely bind this to iproc_dma_data_finish. */ ++ ep->dma.usb_req = NULL; ++ } else { ++ req = list_first_entry(&ep->list_queue, struct iproc_ep_req, list_node); ++ ep->dma.usb_req = &req->usb_req; ++ iproc_dma_data_init(ep); ++ } ++ } ++ } ++ ++ if (ep->dma.usb_req != NULL) { ++ iproc_dma_data_add_ready(ep); ++ iproc_usbd_ep_dma_en(udc->usbd_regs, ep->num, ep->dir); ++ iproc_usbd_ep_nak_clear(udc->usbd_regs, ep->num, ep->dir); ++ } ++} ++ ++ ++/*************************************************************************** ++ * Linux proc file system functions ++ ***************************************************************************/ ++#ifdef CONFIG_USB_GADGET_DEBUG_FILES ++#include ++ ++static const char udc_proc_file_name[] = "driver/" XGS_IPROC_UDC_NAME; ++ ++static int proc_file_show(struct seq_file *s, void *_) ++{ ++ return(0); ++} ++ ++static int proc_file_open(struct inode *inode, struct file *file) ++{ ++ return(single_open(file, proc_file_show, NULL)); ++} ++ ++static struct file_operations udc_proc_file_ops = ++{ ++ .open = proc_file_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++}; ++ ++static void xgs_iproc_udc_proc_create(void) ++{ ++ struct proc_dir_entry *pde; ++ ++ pde = create_proc_entry (udc_proc_file_name, 0, NULL); ++ if (pde) { ++ pde->proc_fops = &udc_proc_file_ops; ++ } ++} ++ ++static void xgs_iproc_udc_proc_remove(void) ++{ ++ remove_proc_entry(udc_proc_file_name, NULL); ++} ++ ++#else ++ ++static void xgs_iproc_udc_proc_create(void) {} ++static void xgs_iproc_udc_proc_remove(void) {} ++ ++#endif ++ ++static const struct of_device_id xgs_iproc_udc_ids[] = { ++ { .compatible = "brcm,usbd,hx4", }, ++ { .compatible = "brcm,usbd,kt2", }, ++ { .compatible = "brcm,usbd,gh", }, ++ { .compatible = "brcm,usbd,sb2", }, ++ { .compatible = "brcm,usbd,hr3", }, ++ { .compatible = "brcm,usbd,gh2", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, xgs_iproc_udc_ids); ++ ++/**************************************************************************** ++ ***************************************************************************/ ++static int xgs_iproc_udc_probe(struct platform_device *pdev) ++{ ++ int ret = ENOERROR; ++ struct device *dev = &pdev->dev; ++ struct device_node *dn = dev->of_node; ++ const struct of_device_id *match; ++ struct iproc_udc *udc = NULL; ++ struct usb_phy *phy; ++ int irq; ++ ++ phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0); ++ if (IS_ERR(phy)) { ++ dev_err(dev, "unable to find transceiver\n"); ++ return PTR_ERR(phy); ++ } ++ ++ if (phy->flags != IPROC_USB_MODE_DEVICE) ++ return -ENODEV; ++ ++ match = of_match_device(xgs_iproc_udc_ids, dev); ++ if (!match) { ++ dev_err(dev, "failed to find USBD in DT\n"); ++ return -ENODEV; ++ } ++ ++ irq = (uint)irq_of_parse_and_map(dn, 0); ++ ++ udc = devm_kzalloc(dev, sizeof(*udc), GFP_KERNEL); ++ if (!udc) { ++ dev_err(dev, "devm_kzalloc() failed\n" ); ++ ret = -ENOMEM; ++ goto err1; ++ } ++ platform_set_drvdata(pdev, udc); ++ ++ udc->dev = dev; ++ spin_lock_init(&udc->lock); ++ ++ udc->usbd_regs = (struct iproc_usbd_regs *)of_iomap(dn, 0); ++ if (!udc->usbd_regs) { ++ dev_err(dev, "unable to iomap USB2D base address\n"); ++ ret = -ENXIO; ++ goto err1; ++ } ++ ++ ret = usb_phy_init(phy); ++ if (ret < 0) { ++ dev_err(dev, "initial usb transceiver failed.\n"); ++ goto err1; ++ } ++ ++ ret = iproc_platform_dma_alloc(pdev, udc); ++ if (ret < 0) { ++ dev_err(dev, "iproc_platform_dma_alloc() failed\n"); ++ goto err1; ++ } ++ ++ /* gadget init */ ++ udc->gadget.name = XGS_IPROC_UDC_NAME; ++ udc->gadget.speed = USB_SPEED_UNKNOWN; ++ udc->gadget.max_speed = USB_SPEED_HIGH; ++ udc->gadget.ops = &xgs_iproc_udc_ops; ++ ++ iproc_udc_ops_init(udc); ++ ++ iproc_usbd_irq_dis(udc->usbd_regs, IPROC_USBD_IRQ_ALL); ++ iproc_usbd_irq_clear(udc->usbd_regs, IPROC_USBD_IRQ_ALL); ++ ++ ret = devm_request_irq(dev, irq, xgs_iproc_udc_isr, 0, ++ XGS_IPROC_UDC_NAME, (void *)udc); ++ if (ret < 0) { ++ dev_err(dev, "error requesting IRQ #%d\n", irq); ++ goto err2; ++ } ++ ++ ret = usb_add_gadget_udc(dev, &udc->gadget); ++ if (ret < 0) { ++ dev_err(dev, "usb_add_gadget_udc() failed\n"); ++ goto err3; ++ } ++ ++ xgs_iproc_udc_proc_create(); ++ ++ return ENOERROR; ++ ++ ++err3: ++ devm_free_irq(dev, irq, udc); ++err2: ++ iproc_platform_dma_free(pdev, udc); ++err1: ++ if (udc->usbd_regs) { ++ iounmap(udc->usbd_regs); ++ udc->usbd_regs = NULL; ++ } ++ if (udc) { ++ kfree(udc); ++ } ++ ++ return ret; ++} ++ ++static int xgs_iproc_udc_remove(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct iproc_udc *udc = platform_get_drvdata(pdev); ++ struct device_node *dn = pdev->dev.of_node; ++ int irq = (uint)irq_of_parse_and_map(dn, 0); ++ ++ if (udc) { ++ xgs_iproc_udc_proc_remove(); ++ ++ usb_del_gadget_udc(&udc->gadget); ++ iproc_udc_ops_finish(udc); ++ ++ platform_set_drvdata(pdev, NULL); ++ iproc_platform_dma_free(pdev, udc); ++ devm_free_irq(dev, irq, udc); ++ ++ if (udc->usbd_regs) { ++ iounmap(udc->usbd_regs); ++ udc->usbd_regs = NULL; ++ } ++ ++ kfree(udc); ++ } ++ ++ return ENOERROR; ++} ++ ++/* ++ * Generic platform device driver definition. ++ */ ++static struct platform_driver xgs_iproc_udc_driver = ++{ ++ .probe = xgs_iproc_udc_probe, ++ .remove = xgs_iproc_udc_remove, ++ .driver = { ++ .name = XGS_IPROC_UDC_NAME, ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(xgs_iproc_udc_ids), ++ }, ++}; ++ ++module_platform_driver(xgs_iproc_udc_driver); ++ ++MODULE_DESCRIPTION("Broadcom USB Device Controller(UDC) driver"); ++MODULE_LICENSE("GPL"); ++MODULE_VERSION("1.0.0"); +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/usb/gadget/udc/xgs_iproc_udc.h b/drivers/usb/gadget/udc/xgs_iproc_udc.h +--- a/drivers/usb/gadget/udc/xgs_iproc_udc.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/usb/gadget/udc/xgs_iproc_udc.h 2017-11-09 17:54:01.737429000 +0800 +@@ -0,0 +1,158 @@ ++/***************************************************************************** ++* Copyright 2006 - 2010 Broadcom Corporation. All rights reserved. ++* ++* Unless you and Broadcom execute a separate written software license ++* agreement governing use of this software, this software is licensed to you ++* under the terms of the GNU General Public License version 2, available at ++* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). ++* ++* Notwithstanding the above, under no circumstances may you combine this ++* software in any way with any other Broadcom software provided under a ++* license other than the GPL, without Broadcom's express prior written ++* consent. ++*****************************************************************************/ ++#ifndef _XGS_IPROC_UDC_H_ ++#define _XGS_IPROC_UDC_H_ ++ ++#include ++#include "xgs_usbd_regs.h" ++ ++#define IPROC_UDC_EP_CNT 7 ++#define IPROC_UDC_CTRL_MAX_PKG_SIZE 64 ++#define IPROC_UDC_EP_MAX_PKG_SIZE 512 ++ ++/* ++ * Some unsigned number trickery for indexing into DMA descriptor chain. If the ++ * decriptor count is some power of 2, then we can use the mask to extract ++ * an index and not worry about wrap around as the unsigned variables are ++ * incremented. E.g. in following, IDX(0), IDX(4), IDX(8), ..., IDX(0xffffc) ++ * all produce the same result, i.e. 0. ++ */ ++#define IPROC_EP_DMA_DESC_CNT 1 ++#define IPROC_EP_DMA_DESC_IDX_MASK (IPROC_EP_DMA_DESC_CNT - 1) ++#define IPROC_EP_DMA_DESC_IDX(_idx) ((_idx) & IPROC_EP_DMA_DESC_IDX_MASK) ++ ++/* Some DWC UDC DMA descriptor layout definitions. See datasheet for details. */ ++ ++struct iproc_udc_dma_setup { ++ unsigned int status; ++ unsigned int reserved; ++ unsigned int data1; ++ unsigned int data2; ++}; ++ ++struct iproc_udc_dma_desc { ++ unsigned int status; ++ unsigned int reserved; ++ unsigned int buf_addr; ++ unsigned int next_addr; ++}; ++ ++/* ++ * Common DMA descriptor layout used for all endpoints. Only control endpoints ++ * need the setup descriptor, but in order to simply things it is defined for ++ * all. It may be possible to omit this altogether, and just use one of data ++ * descriptors for setup instead. The control transfer protocol should allow ++ * this to be done. ++ */ ++struct iproc_ep_dma { ++ struct iproc_udc_dma_setup setup; ++ struct iproc_udc_dma_desc desc[IPROC_EP_DMA_DESC_CNT]; ++}; ++ ++/* Structure used for DMA descriptor allocation. Not really necessary but convenient. */ ++ ++struct iproc_udc_dma { ++ struct iproc_ep_dma ep[IPROC_UDC_EP_CNT]; ++}; ++ ++/* ++ * Structure used to hold endpoint specific information. There's one of these for ++ * each endpoint. ++ * ++ * The Rx/Tx FIFO sizes are used for RAM allocation purposes. Each transfer ++ * direction has its own RAM that is used for all the FIFOs in that direction. ++ * The RAM gets segmented (allocated) as each endpoint gets enabled. This dynamic ++ * allocation FIFO sizes gives flexibility, and does not require that an ++ * endpoint's size be fixed at run-time or during compilation. If there's not ++ * enough FIFO RAM as required by a gadget's endpoint definitions, then an ++ * error will occur for the enabling of any endpoints after the FIFO RAM has ++ * become exhausted. ++ * ++ * The DMA virtual address is used for all descriptor operations. The DMA ++ * physical address is for convenience (setting hardware registers, obtaining ++ * addresses for descriptor chaining, etc.). The DMA descriptors are not ++ * allocated on a per-endpoint basis. These are just pointers into the ++ * large block that was allocated for all endpoints. ++ */ ++struct iproc_ep { ++ struct usb_ep usb_ep; /* usb_gadget.h */ ++ const struct usb_endpoint_descriptor *desc; /* usb/ch9.h */ ++ struct list_head list_queue; /* active BCM_UDC_EP_REQ's for the endpoint */ ++ struct iproc_udc *udc; /* endpoint owner (UDC controller) */ ++ unsigned int num; ++ unsigned int dir; /* USB_DIR_xxx (direction) */ ++ unsigned int type; /* USB_ENDPOINT_XFER_xxx */ ++ unsigned int beq_addr; /* dirn | type */ ++ unsigned int stopped : 1; ++ struct { ++ struct iproc_ep_dma *vir_addr; ++ struct iproc_ep_dma *phy_addr; ++ struct usb_request *usb_req; /* Current request being DMA'd */ ++ ++ /** @todo Some of the below are duplicates of usb_request elements. Use usb_request instead. */ ++ unsigned int max_buf_len; /* Max buffer length to use with a descriptor */ ++ unsigned int done_len; /* Length of request DMA'd so far */ ++ unsigned int todo_len; /* Length of request left to DMA */ ++ unsigned int add_idx; /* descriptor chain index */ ++ unsigned int rm_idx; /* descriptor chain index */ ++ unsigned int buf_addr; /* Location in request to DMA */ ++ unsigned int frame_num; /* Frame number for ISOC transfers */ ++ unsigned int frame_incr; /* Frame number increment (period) */ ++ unsigned int status; ++ unsigned int done; /* DMA and USB transfer completion indication (IN_DMA_DONE and IN_XFER_DONE) */ ++ void *align_buff; /* Aligned buffer. Only used if usb_req buffer not aligned properly. */ ++ dma_addr_t align_addr; /* Aligned buffer physical address */ ++ unsigned int align_len; /* Aligned buffer length */ ++ } dma; ++}; ++ ++/* ++ * Structure used to hold controller information. There should be one of these ++ * for each controller. Most likely there's only one. ++ * ++ * The Rx/Tx FIFO space are used for RAM allocation purposes. These track how ++ * much RAM is available for use as a FIFO. When an endpoint is enabled, these ++ * are check to see if there's enough RAM for a FIFO of the desired length as ++ * implied by the max packet size. ++ */ ++struct iproc_udc { ++ struct usb_gadget gadget; /* usb_gadget.h */ ++ struct usb_gadget_driver *gadget_driver; /* usb_gadget.h */ ++ struct completion *dev_release; /* Used for coordination during device removal */ ++ spinlock_t lock; ++ struct device *dev; ++ unsigned int irq_num; ++ struct iproc_ep ep[IPROC_UDC_EP_CNT]; ++ struct iproc_usbd_regs *usbd_regs; ++ struct { ++ struct iproc_udc_dma *vir_addr; ++ struct iproc_udc_dma *phy_addr; ++ } dma; ++ unsigned int vbus_active : 1; /* Indicates if VBUS is present */ ++ unsigned int pullup_on : 1; /* Indicates if pull up is on */ ++}; ++ ++/* ++ * Structure used to hold an endpoint transfer request. Can be any number of ++ * these for an endpoint. ++ */ ++struct iproc_ep_req { ++ struct usb_request usb_req; /* usb_gadget.h */ ++ struct list_head list_node; /* For linking in the BCM_UDC_EP request queue */ ++ dma_addr_t orig_dma_addr; /* Original buffer DMA address (physical). */ ++ unsigned dma_mapped : 1; /* Indicates if address mapping req'd. See usb_gadget.h */ ++ unsigned dma_aligned : 1; /* Indicates if buffer duplication done for alignment. */ ++}; ++ ++#endif /* _XGS_IPROC_UDC_H_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/usb/gadget/udc/xgs_usbd_regs.h b/drivers/usb/gadget/udc/xgs_usbd_regs.h +--- a/drivers/usb/gadget/udc/xgs_usbd_regs.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/usb/gadget/udc/xgs_usbd_regs.h 2017-11-09 17:54:01.738446000 +0800 +@@ -0,0 +1,995 @@ ++/***************************************************************************** ++* Copyright 2003 - 2009 Broadcom Corporation. All rights reserved. ++* ++* Unless you and Broadcom execute a separate written software license ++* agreement governing use of this software, this software is licensed to you ++* under the terms of the GNU General Public License version 2, available at ++* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). ++* ++* Notwithstanding the above, under no circumstances may you combine this ++* software in any way with any other Broadcom software provided under a ++* license other than the GPL, without Broadcom's express prior written ++* consent. ++*****************************************************************************/ ++#ifndef _USBD_REGS_H_ ++#define _USBD_REGS_H_ ++ ++#include ++ ++#define IPROC_USBD_MULTI_RX_FIFO 0 ++ ++#define IPROC_USBD_EP_CFG_CNT 10 ++#define IPROC_USBD_REG_EP_CNT 16 ++ ++#define IPROC_USBD_SPEED_UNKNOWN 0 ++#define IPROC_USBD_SPEED_LOW 1 ++#define IPROC_USBD_SPEED_FULL 2 ++#define IPROC_USBD_SPEED_HIGH 3 ++ ++#define IPROC_USBD_EP_DIR_IN 0x80 ++#define IPROC_USBD_EP_DIR_OUT 0x00 ++ ++#define IPROC_USBD_EP_TYPE_CTRL 0 ++#define IPROC_USBD_EP_TYPE_ISOC 1 ++#define IPROC_USBD_EP_TYPE_BULK 2 ++#define IPROC_USBD_EP_TYPE_INTR 3 ++ ++#define IPROC_USBD_IRQ_REMOTEWAKEUP_DELTA IPROC_USBD_REG_INTR_REMOTE_WAKEUP_DELTA ++#define IPROC_USBD_IRQ_SPEED_ENUM_DONE IPROC_USBD_REG_INTR_SPD_ENUM_DONE ++#define IPROC_USBD_IRQ_SOF_DETECTED IPROC_USBD_REG_INTR_SOF_RX ++#define IPROC_USBD_IRQ_BUS_SUSPEND IPROC_USBD_REG_INTR_BUS_SUSPEND ++#define IPROC_USBD_IRQ_BUS_RESET IPROC_USBD_REG_INTR_BUS_RESET ++#define IPROC_USBD_IRQ_BUS_IDLE IPROC_USBD_REG_INTR_BUS_IDLE ++#define IPROC_USBD_IRQ_SET_INTF IPROC_USBD_REG_INTR_SET_INTF_RX ++#define IPROC_USBD_IRQ_SET_CFG IPROC_USBD_REG_INTR_SET_CFG_RX ++#define IPROC_USBD_IRQ_ALL (IPROC_USBD_IRQ_REMOTEWAKEUP_DELTA | \ ++ IPROC_USBD_IRQ_SPEED_ENUM_DONE | \ ++ IPROC_USBD_IRQ_SOF_DETECTED | \ ++ IPROC_USBD_IRQ_BUS_SUSPEND | \ ++ IPROC_USBD_IRQ_BUS_RESET | \ ++ IPROC_USBD_IRQ_BUS_IDLE | \ ++ IPROC_USBD_IRQ_SET_INTF | \ ++ IPROC_USBD_IRQ_SET_CFG) ++ ++#define IPROC_USBD_EP_STAT_DMA_ERROR IPROC_USBD_REG_EP_FIFO_STATUS_AHB_BUS_ERROR ++#define IPROC_USBD_EP_STAT_DMA_BUF_UNAVAIL IPROC_USBD_REG_EP_FIFO_STATUS_DMA_BUF_NOT_AVAIL ++#define IPROC_USBD_EP_STAT_IN_TOKEN_RX IPROC_USBD_REG_EP_FIFO_STATUS_IN_TOKEN_RX ++#define IPROC_USBD_EP_STAT_IN_DMA_DONE IPROC_USBD_REG_EP_FIFO_STATUS_IN_DMA_DONE ++#define IPROC_USBD_EP_STAT_IN_FIFO_EMPTY IPROC_USBD_REG_EP_FIFO_STATUS_IN_FIFO_EMPTY ++#define IPROC_USBD_EP_STAT_IN_XFER_DONE IPROC_USBD_REG_EP_FIFO_STATUS_IN_XFER_DONE ++#define IPROC_USBD_EP_STAT_OUT_DMA_DATA_DONE IPROC_USBD_REG_EP_FIFO_STATUS_OUT_DMA_DATA_DONE ++#define IPROC_USBD_EP_STAT_OUT_DMA_SETUP_DONE IPROC_USBD_REG_EP_FIFO_STATUS_OUT_DMA_SETUP_DONE ++#define IPROC_USBD_EP_STAT_ALL (IPROC_USBD_EP_STAT_DMA_ERROR | \ ++ IPROC_USBD_EP_STAT_DMA_BUF_UNAVAIL | \ ++ IPROC_USBD_EP_STAT_IN_TOKEN_RX | \ ++ IPROC_USBD_EP_STAT_IN_DMA_DONE | \ ++ IPROC_USBD_EP_STAT_IN_XFER_DONE | \ ++ IPROC_USBD_EP_STAT_OUT_DMA_DATA_DONE | \ ++ IPROC_USBD_EP_STAT_OUT_DMA_SETUP_DONE) ++ ++ ++#define REG8_RSVD(start, end) uint8_t rsvd_##start[(end - start) / sizeof(uint8_t)] ++#define REG16_RSVD(start, end) uint16_t rsvd_##start[(end - start) / sizeof(uint16_t)] ++#define REG32_RSVD(start, end) uint rsvd_##start[(end - start) / sizeof(uint)] ++ ++struct iproc_usbd_ep_fifo_regs { ++ uint ctrl; ++ uint status; ++ uint size1; ++ uint size2; /* Buf Size OUT/Max PKT SIZE */ ++ uint buf_addr; ++ uint desc_addr; ++ REG32_RSVD(0x18, 0x20); ++}; ++ ++struct iproc_usbd_regs { ++ struct iproc_usbd_ep_fifo_regs ep_fifo_in[IPROC_USBD_REG_EP_CNT]; ++ struct iproc_usbd_ep_fifo_regs ep_fifo_out[IPROC_USBD_REG_EP_CNT]; ++ uint dev_cfg; ++ uint dev_ctrl; ++ uint dev_status; ++ uint dev_irq_status; ++ uint dev_irq_mask; ++ uint ep_irq_status; ++ uint ep_irq_mask; ++ uint test_mode; ++ uint rel_num; ++ REG32_RSVD(0x424, 0x500); ++ REG32_RSVD(0x500, 0x504); ++ uint ep_cfg[IPROC_USBD_REG_EP_CNT]; ++ REG32_RSVD(0x544, 0x800); ++ uint rx_fifo[256]; ++ uint tx_fifo[256]; ++ uint strap; ++}; ++ ++ ++struct iproc_usbd_idm_regs { ++ REG32_RSVD(0x000, 0x408); ++ uint io_ctrl; ++ REG32_RSVD(0x40C, 0x500); ++ uint io_status; ++ REG32_RSVD(0x504, 0x800); ++ uint reset_ctrl; ++ uint reset_status; ++ REG32_RSVD(0x808, 0xA00); ++ uint irq_status; ++}; ++ ++/* ++ * The endpoint type field in the FIFO control register has the same enumeration ++ * as the USB protocol. Not going to define it here. ++ */ ++#define IPROC_USBD_REG_EP_FIFO_CTRL_OUT_FLUSH_ENABLE (1 << 12) ++#define IPROC_USBD_REG_EP_FIFO_CTRL_OUT_CLOSE_DESC (1 << 11) ++#define IPROC_USBD_REG_EP_FIFO_CTRL_IN_SEND_NULL (1 << 10) ++#define IPROC_USBD_REG_EP_FIFO_CTRL_OUT_DMA_ENABLE (1 << 9) ++#define IPROC_USBD_REG_EP_FIFO_CTRL_NAK_CLEAR (1 << 8) ++#define IPROC_USBD_REG_EP_FIFO_CTRL_NAK_SET (1 << 7) ++#define IPROC_USBD_REG_EP_FIFO_CTRL_NAK_IN_PROGRESS (1 << 6) ++#define IPROC_USBD_REG_EP_FIFO_CTRL_TYPE_SHIFT 4 ++#define IPROC_USBD_REG_EP_FIFO_CTRL_TYPE_MASK (3 << IPROC_USBD_REG_EP_FIFO_CTRL_TYPE_SHIFT) ++#define IPROC_USBD_REG_EP_FIFO_CTRL_IN_DMA_ENABLE (1 << 3) ++#define IPROC_USBD_REG_EP_FIFO_CTRL_SNOOP_ENABLE (1 << 2) ++#define IPROC_USBD_REG_EP_FIFO_CTRL_IN_FLUSH_ENABLE (1 << 1) ++#define IPROC_USBD_REG_EP_FIFO_CTRL_STALL_ENABLE (1 << 0) ++ ++#define IPROC_USBD_REG_EP_FIFO_STATUS_CLOSE_DESC_CLEAR (1 << 28) ++#define IPROC_USBD_REG_EP_FIFO_STATUS_IN_XFER_DONE (1 << 27) ++#define IPROC_USBD_REG_EP_FIFO_STATUS_STALL_SET_RX (1 << 26) ++#define IPROC_USBD_REG_EP_FIFO_STATUS_STALL_CLEAR_RX (1 << 25) ++#define IPROC_USBD_REG_EP_FIFO_STATUS_IN_FIFO_EMPTY (1 << 24) ++#define IPROC_USBD_REG_EP_FIFO_STATUS_IN_DMA_DONE (1 << 10) ++#define IPROC_USBD_REG_EP_FIFO_STATUS_AHB_BUS_ERROR (1 << 9) ++#define IPROC_USBD_REG_EP_FIFO_STATUS_OUT_FIFO_EMPTY (1 << 8) ++#define IPROC_USBD_REG_EP_FIFO_STATUS_DMA_BUF_NOT_AVAIL (1 << 7) ++#define IPROC_USBD_REG_EP_FIFO_STATUS_IN_TOKEN_RX (1 << 6) ++#define IPROC_USBD_REG_EP_FIFO_STATUS_OUT_DMA_SETUP_DONE (1 << 5) ++#define IPROC_USBD_REG_EP_FIFO_STATUS_OUT_DMA_DATA_DONE (1 << 4) ++ ++#define IPROC_USBD_REG_EP_FIFO_SIZE1_OUT_ISOC_PID_SHIFT 16 ++#define IPROC_USBD_REG_EP_FIFO_SIZE1_OUT_ISOC_PID_MASK (3 << IPROC_USBD_REG_EP_FIFO_SIZE1_OUT_ISOC_PID_SHIFT) ++#define IPROC_USBD_REG_EP_FIFO_SIZE1_IN_DEPTH_SHIFT 0 ++#define IPROC_USBD_REG_EP_FIFO_SIZE1_IN_DEPTH_MASK (0xffff << IPROC_USBD_REG_EP_FIFO_SIZE1_IN_DEPTH_SHIFT) ++#define IPROC_USBD_REG_EP_FIFO_SIZE1_OUT_FRAME_NUM_SHIFT IPROC_USBD_REG_EP_FIFO_SIZE1_IN_DEPTH_SHIFT ++#define IPROC_USBD_REG_EP_FIFO_SIZE1_OUT_FRAME_NUM_MASK IPROC_USBD_REG_EP_FIFO_SIZE1_IN_DEPTH_MASK ++ ++#define IPROC_USBD_REG_EP_FIFO_SIZE2_OUT_DEPTH_SHIFT 16 ++#define IPROC_USBD_REG_EP_FIFO_SIZE2_OUT_DEPTH_MASK (0xffff << IPROC_USBD_REG_EP_FIFO_SIZE2_OUT_DEPTH_SHIFT) ++#define IPROC_USBD_REG_EP_FIFO_SIZE2_PKT_MAX_SHIFT 0 ++#define IPROC_USBD_REG_EP_FIFO_SIZE2_PKT_MAX_MASK (0xffff << IPROC_USBD_REG_EP_FIFO_SIZE2_PKT_MAX_SHIFT) ++ ++/* ++ * The endpoint type field in the config register has the same enumeration ++ * as the USB protocol. Not going to define it here. ++ */ ++#define IPROC_USBD_REG_EP_CFG_PKT_MAX_SHIFT 19 ++#define IPROC_USBD_REG_EP_CFG_PKT_MAX_MASK (0x7ff << IPROC_USBD_REG_EP_CFG_PKT_MAX_SHIFT) ++#define IPROC_USBD_REG_EP_CFG_ALT_NUM_SHIFT 15 ++#define IPROC_USBD_REG_EP_CFG_ALT_NUM_MASK (0xf << IPROC_USBD_REG_EP_CFG_ALT_NUM_SHIFT) ++#define IPROC_USBD_REG_EP_CFG_INTF_NUM_SHIFT 11 ++#define IPROC_USBD_REG_EP_CFG_INTF_NUM_MASK (0xf << IPROC_USBD_REG_EP_CFG_INTF_NUM_SHIFT) ++#define IPROC_USBD_REG_EP_CFG_CFG_NUM_SHIFT 7 ++#define IPROC_USBD_REG_EP_CFG_CFG_NUM_MASK (0xf << IPROC_USBD_REG_EP_CFG_CFG_NUM_SHIFT) ++#define IPROC_USBD_REG_EP_CFG_TYPE_SHIFT 5 ++#define IPROC_USBD_REG_EP_CFG_TYPE_MASK (0x3 << IPROC_USBD_REG_EP_CFG_TYPE_SHIFT) ++#define IPROC_USBD_REG_EP_CFG_DIRN_IN (1 << 4) ++#define IPROC_USBD_REG_EP_CFG_DIRN_OUT 0 ++#define IPROC_USBD_REG_EP_CFG_FIFO_NUM_SHIFT 0 ++#define IPROC_USBD_REG_EP_CFG_FIFO_NUM_MASK (0xf << IPROC_USBD_REG_EP_CFG_FIFO_NUM_SHIFT) ++ ++/* Endpoint Interrupt register definitions */ ++#define IPROC_USBD_REG_EP_INTR_OUT_SHIFT 16 ++#define IPROC_USBD_REG_EP_INTR_OUT_MASK (0xffff << IPROC_USBD_REG_EP_INTR_OUT_SHIFT) ++#define IPROC_USBD_REG_EP_INTR_IN_SHIFT 0 ++#define IPROC_USBD_REG_EP_INTR_IN_MASK (0xffff << IPROC_USBD_REG_EP_INTR_IN_SHIFT) ++ ++/* Device Controller register definitions */ ++#define IPROC_USBD_REG_CFG_ULPI_DDR_ENABLE (1 << 19) ++#define IPROC_USBD_REG_CFG_SET_DESCRIPTOR_ENABLE (1 << 18) ++#define IPROC_USBD_REG_CFG_CSR_PROGRAM_ENABLE (1 << 17) ++#define IPROC_USBD_REG_CFG_HALT_STALL_ENABLE (1 << 16) ++#define IPROC_USBD_REG_CFG_HS_TIMEOUT_CALIB_SHIFT 13 ++#define IPROC_USBD_REG_CFG_HS_TIMEOUT_CALIB_MASK (7 << IPROC_USBD_REG_CFG_HS_TIMEOUT_CALIB_SHIFT) ++#define IPROC_USBD_REG_CFG_FS_TIMEOUT_CALIB_SHIFT 10 ++#define IPROC_USBD_REG_CFG_FS_TIMEOUT_CALIB_MASK (7 << IPROC_USBD_REG_CFG_FS_TIMEOUT_CALIB_SHIFT) ++#define IPROC_USBD_REG_CFG_STATUS_1_ENABLE (1 << 8) ++#define IPROC_USBD_REG_CFG_STATUS_ENABLE (1 << 7) ++#define IPROC_USBD_REG_CFG_UTMI_BI_DIRN_ENABLE (1 << 6) ++#define IPROC_USBD_REG_CFG_UTMI_8BIT_ENABLE (1 << 5) ++#define IPROC_USBD_REG_CFG_SYNC_FRAME_ENABLE (1 << 4) ++#define IPROC_USBD_REG_CFG_SELF_PWR_ENABLE (1 << 3) ++#define IPROC_USBD_REG_CFG_REMOTE_WAKEUP_ENABLE (1 << 2) ++#define IPROC_USBD_REG_CFG_SPD_SHIFT 0 ++#define IPROC_USBD_REG_CFG_SPD_MASK (3 << IPROC_USBD_REG_CFG_SPD_SHIFT) ++#define IPROC_USBD_REG_CFG_SPD_HS (0 << IPROC_USBD_REG_CFG_SPD_SHIFT) ++#define IPROC_USBD_REG_CFG_SPD_FS (1 << IPROC_USBD_REG_CFG_SPD_SHIFT) ++#define IPROC_USBD_REG_CFG_SPD_LS (2 << IPROC_USBD_REG_CFG_SPD_SHIFT) ++#define IPROC_USBD_REG_CFG_SPD_FS_48MHZ (3 << IPROC_USBD_REG_CFG_SPD_SHIFT) ++ ++#define IPROC_USBD_REG_CTRL_DMA_OUT_THRESHOLD_LEN_SHIFT 24 ++#define IPROC_USBD_REG_CTRL_DMA_OUT_THRESHOLD_LEN_MASK (0xff << IPROC_USBD_REG_CTRL_DMA_OUT_THRESHOLD_LEN_SHIFT) ++#define IPROC_USBD_REG_CTRL_DMA_BURST_LEN_SHIFT 16 ++#define IPROC_USBD_REG_CTRL_DMA_BURST_LEN_MASK (0xff << IPROC_USBD_REG_CTRL_DMA_BURST_LEN_SHIFT) ++#define IPROC_USBD_REG_CTRL_OUT_FIFO_FLUSH_ENABLE (1 << 14) ++#define IPROC_USBD_REG_CTRL_CSR_DONE (1 << 13) ++#define IPROC_USBD_REG_CTRL_OUT_NAK_ALL_ENABLE (1 << 12) ++#define IPROC_USBD_REG_CTRL_DISCONNECT_ENABLE (1 << 10) ++#define IPROC_USBD_REG_CTRL_DMA_MODE_ENABLE (1 << 9) ++#define IPROC_USBD_REG_CTRL_DMA_BURST_ENABLE (1 << 8) ++#define IPROC_USBD_REG_CTRL_DMA_OUT_THRESHOLD_ENABLE (1 << 7) ++#define IPROC_USBD_REG_CTRL_DMA_BUFF_FILL_MODE_ENABLE (1 << 6) ++#define IPROC_USBD_REG_CTRL_ENDIAN_BIG_ENABLE (1 << 5) ++#define IPROC_USBD_REG_CTRL_DMA_DESC_UPDATE_ENABLE (1 << 4) ++#define IPROC_USBD_REG_CTRL_DMA_IN_ENABLE (1 << 3) /*TX DMA Enable */ ++#define IPROC_USBD_REG_CTRL_DMA_OUT_ENABLE (1 << 2) /*RX DMA Enable */ ++#define IPROC_USBD_REG_CTRL_RESUME_SIGNAL_ENABLE (1 << 0) ++#define IPROC_USBD_REG_CTRL_LE_ENABLE 0 /*^BCM5892 */ ++ ++#define IPROC_USBD_REG_STAT_SOF_FRAME_NUM_SHIFT 18 ++#define IPROC_USBD_REG_STAT_SOF_FRAME_NUM_MASK (0x3ffff << IPROC_USBD_REG_STAT_SOF_FRAME_NUM_SHIFT) ++#define IPROC_USBD_REG_STAT_REMOTE_WAKEUP_ALLOWED (1 << 17) ++#define IPROC_USBD_REG_STAT_PHY_ERROR (1 << 16) ++#define IPROC_USBD_REG_STAT_OUT_FIFO_EMPTY (1 << 15) ++#define IPROC_USBD_REG_STAT_SPD_SHIFT 13 ++#define IPROC_USBD_REG_STAT_SPD_MASK (3 << IPROC_USBD_REG_STAT_SPD_SHIFT) ++#define IPROC_USBD_REG_STAT_SPD_HS (0 << IPROC_USBD_REG_STAT_SPD_SHIFT) ++#define IPROC_USBD_REG_STAT_SPD_FS (1 << IPROC_USBD_REG_STAT_SPD_SHIFT) ++#define IPROC_USBD_REG_STAT_SPD_LS (2 << IPROC_USBD_REG_STAT_SPD_SHIFT) ++#define IPROC_USBD_REG_STAT_SPD_FS_48MHZ (3 << IPROC_USBD_REG_STAT_SPD_SHIFT) ++#define IPROC_USBD_REG_STAT_BUS_SUSPENDED (1 << 12) ++#define IPROC_USBD_REG_STAT_ALT_NUM_SHIFT 8 ++#define IPROC_USBD_REG_STAT_ALT_NUM_MASK (0xf << IPROC_USBD_REG_STAT_ALT_NUM_SHIFT) ++#define IPROC_USBD_REG_STAT_INTF_NUM_SHIFT 4 ++#define IPROC_USBD_REG_STAT_INTF_NUM_MASK (0xf << IPROC_USBD_REG_STAT_INTF_NUM_SHIFT) ++#define IPROC_USBD_REG_STAT_CFG_NUM_SHIFT 0 ++#define IPROC_USBD_REG_STAT_CFG_NUM_MASK (0xf << IPROC_USBD_REG_STAT_CFG_NUM_SHIFT) ++ ++#define IPROC_USBD_REG_INTR_REMOTE_WAKEUP_DELTA (1 << 7) /*Remote Wakeup Delta*/ ++#define IPROC_USBD_REG_INTR_SPD_ENUM_DONE (1 << 6) /*ENUM Speed Completed*/ ++#define IPROC_USBD_REG_INTR_SOF_RX (1 << 5) /*SOF Token Detected */ ++#define IPROC_USBD_REG_INTR_BUS_SUSPEND (1 << 4) /*SUSPEND State Detected*/ ++#define IPROC_USBD_REG_INTR_BUS_RESET (1 << 3) /*RESET State Detected */ ++#define IPROC_USBD_REG_INTR_BUS_IDLE (1 << 2) /*IDLE State Detected*/ ++#define IPROC_USBD_REG_INTR_SET_INTF_RX (1 << 1) /*Received SET_INTERFACE CMD*/ ++#define IPROC_USBD_REG_INTR_SET_CFG_RX (1 << 0) /*Received SET_CONFIG CMD*/ ++ ++/* DMA Descriptor definitions */ ++#define IPROC_USBD_REG_DMA_STAT_BUF_SHIFT 30 ++#define IPROC_USBD_REG_DMA_STAT_BUF_HOST_READY (0 << IPROC_USBD_REG_DMA_STAT_BUF_SHIFT) ++#define IPROC_USBD_REG_DMA_STAT_BUF_DMA_BUSY (1 << IPROC_USBD_REG_DMA_STAT_BUF_SHIFT) ++#define IPROC_USBD_REG_DMA_STAT_BUF_DMA_DONE (2 << IPROC_USBD_REG_DMA_STAT_BUF_SHIFT) ++#define IPROC_USBD_REG_DMA_STAT_BUF_HOST_BUSY (3 << IPROC_USBD_REG_DMA_STAT_BUF_SHIFT) ++#define IPROC_USBD_REG_DMA_STAT_BUF_MASK (3 << IPROC_USBD_REG_DMA_STAT_BUF_SHIFT) ++#define IPROC_USBD_REG_DMA_STAT_RX_SHIFT 28 ++#define IPROC_USBD_REG_DMA_STAT_RX_SUCCESS (0 << IPROC_USBD_REG_DMA_STAT_RX_SHIFT) ++#define IPROC_USBD_REG_DMA_STAT_RX_ERR_DESC (1 << IPROC_USBD_REG_DMA_STAT_RX_SHIFT) ++#define IPROC_USBD_REG_DMA_STAT_RX_ERR_BUF (3 << IPROC_USBD_REG_DMA_STAT_RX_SHIFT) ++#define IPROC_USBD_REG_DMA_STAT_RX_MASK (3 << IPROC_USBD_REG_DMA_STAT_RX_SHIFT) ++#define IPROC_USBD_REG_DMA_STAT_CFG_NUM_SHIFT 24 ++#define IPROC_USBD_REG_DMA_STAT_CFG_NUM_MASK (0xf << IPROC_USBD_REG_DMA_STAT_CFG_NUM_SHIFT) ++#define IPROC_USBD_REG_DMA_STAT_INTF_NUM_SHIFT 20 ++#define IPROC_USBD_REG_DMA_STAT_INTF_NUM_MASK (0xf << IPROC_USBD_REG_DMA_STAT_INTF_NUM_SHIFT) ++#define IPROC_USBD_REG_DMA_STAT_ALT_NUM_SHIFT 16 ++#define IPROC_USBD_REG_DMA_STAT_ALT_NUM_MASK (0xf << IPROC_USBD_REG_DMA_STAT_ALT_NUM_SHIFT) ++#define IPROC_USBD_REG_DMA_STAT_LAST_DESC (1 << 27) ++#define IPROC_USBD_REG_DMA_STAT_FRAME_NUM_SHIFT 16 ++#define IPROC_USBD_REG_DMA_STAT_FRAME_NUM_MASK (0x7ff << IPROC_USBD_REG_DMA_STAT_FRAME_NUM_SHIFT) ++#define IPROC_USBD_REG_DMA_STAT_BYTE_CNT_SHIFT 0 ++#define IPROC_USBD_REG_DMA_STAT_ISO_PID_SHIFT 14 ++#define IPROC_USBD_REG_DMA_STAT_ISO_PID_MASK (0x3 << IPROC_USBD_REG_DMA_STAT_ISO_PID_SHIFT) ++#define IPROC_USBD_REG_DMA_STAT_ISO_BYTE_CNT_SHIFT IPROC_USBD_REG_DMA_STAT_BYTE_CNT_SHIFT ++#define IPROC_USBD_REG_DMA_STAT_ISO_BYTE_CNT_MASK (0x3fff << IPROC_USBD_REG_DMA_STAT_ISO_BYTE_CNT_SHIFT) ++#define IPROC_USBD_REG_DMA_STAT_NON_ISO_BYTE_CNT_SHIFT IPROC_USBD_REG_DMA_STAT_BYTE_CNT_SHIFT ++#define IPROC_USBD_REG_DMA_STAT_NON_ISO_BYTE_CNT_MASK (0xffff << IPROC_USBD_REG_DMA_STAT_NON_ISO_BYTE_CNT_SHIFT) ++ ++/* USB2D IDM definitions */ ++#define IPROC_USB2D_IDM_REG_IO_CTRL_DIRECT_CLK_ENABLE (1 << 0) ++#define IPROC_USB2D_IDM_REG_RESET_CTRL_RESET (1 << 0) ++ ++/* Inline Function Definitions */ ++static inline uint ++usbd_reg32_read(volatile uint *reg) ++{ ++ return (le32_to_cpu(*reg)); ++} ++ ++static inline void ++usbd_reg32_write(volatile uint *reg, uint value) ++{ ++ *reg = cpu_to_le32(value); ++} ++ ++static inline void ++usbd_reg32_bits_set(volatile uint *reg, uint bits) ++{ ++ uint tmp; ++ tmp = usbd_reg32_read(reg); ++ tmp |= bits; ++ usbd_reg32_write(reg, tmp); ++} ++ ++static inline void ++usbd_reg32_bits_clear(volatile uint *reg, uint bits) ++{ ++ uint tmp; ++ tmp = usbd_reg32_read(reg); ++ tmp &= ~bits; ++ usbd_reg32_write(reg, tmp); ++} ++ ++static inline void ++usbd_reg32_bits_modify(volatile uint *reg, uint mask, uint value) ++{ ++ uint tmp; ++ tmp = usbd_reg32_read(reg); ++ tmp &= ~mask; ++ tmp |= value; ++ usbd_reg32_write(reg, tmp); ++} ++ ++#define IPROC_USBD_READ(_r) usbd_reg32_read(&_r) ++#define IPROC_USBD_WRITE(_r, _v) usbd_reg32_write(&_r, _v) ++#define IPROC_USBD_BITS_SET(_r, _b) usbd_reg32_bits_set(&_r, _b) ++#define IPROC_USBD_BITS_CLEAR(_r, _b) usbd_reg32_bits_clear(&_r, _b) ++#define IPROC_USBD_BITS_MODIFY(_r, _m, _v) usbd_reg32_bits_modify(&_r, _m, _v) ++ ++/***************************************************************************** ++* @brief Connect / Disconnect to USB BUS ++*****************************************************************************/ ++static inline void iproc_usbd_bus_conn(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_CLEAR(base->dev_ctrl, IPROC_USBD_REG_CTRL_DISCONNECT_ENABLE); ++} ++ ++static inline void iproc_usbd_bus_disconn(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_SET(base->dev_ctrl, IPROC_USBD_REG_CTRL_DISCONNECT_ENABLE); ++} ++ ++/***************************************************************************** ++* @brief USB BUS suspend status ++* @return ++* true : BUS is in suspend state ++* false : BUS is not in suspend state ++*****************************************************************************/ ++static inline bool iproc_usbd_bus_suspend(struct iproc_usbd_regs *base) ++{ ++ return (IPROC_USBD_READ(base->dev_status) & IPROC_USBD_REG_STAT_BUS_SUSPENDED) ? true : false; ++} ++ ++/***************************************************************************** ++* @brief Retrieve setting numbers from last Rx'd SET_CONFIGURATION or ++* SET_INTERFACE request ++* @return ++* Setting Number ++*****************************************************************************/ ++static inline uint iproc_usbd_alt_num(struct iproc_usbd_regs *base) ++{ ++ return ((IPROC_USBD_READ(base->dev_status) & IPROC_USBD_REG_STAT_ALT_NUM_MASK) >> IPROC_USBD_REG_STAT_ALT_NUM_SHIFT); ++} ++ ++static inline uint iproc_usbd_cfg_num(struct iproc_usbd_regs *base) ++{ ++ return ((IPROC_USBD_READ(base->dev_status) & IPROC_USBD_REG_STAT_CFG_NUM_MASK) >> IPROC_USBD_REG_STAT_CFG_NUM_SHIFT); ++} ++ ++static inline uint iproc_usbd_intf_num(struct iproc_usbd_regs *base) ++{ ++ return ((IPROC_USBD_READ(base->dev_status) & IPROC_USBD_REG_STAT_INTF_NUM_MASK) >> IPROC_USBD_REG_STAT_INTF_NUM_SHIFT); ++} ++ ++ ++/***************************************************************************** ++* @brief Disable / Enable DMA operations at the device level (all endpoints) ++*****************************************************************************/ ++static inline void iproc_usbd_dma_dis(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_CLEAR(base->dev_ctrl, (IPROC_USBD_REG_CTRL_DMA_IN_ENABLE | IPROC_USBD_REG_CTRL_DMA_OUT_ENABLE)); ++} ++ ++static inline void iproc_usbd_dma_en(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_SET(base->dev_ctrl, (IPROC_USBD_REG_CTRL_DMA_IN_ENABLE | IPROC_USBD_REG_CTRL_DMA_OUT_ENABLE)); ++} ++ ++static inline bool iproc_usbd_dma_status(struct iproc_usbd_regs *base) ++{ ++ return (IPROC_USBD_READ(base->dev_ctrl) & IPROC_USBD_REG_CTRL_DMA_OUT_ENABLE ? true : false); ++} ++ ++/***************************************************************************** ++* @brief Retrieve Frame number contained in last Rx'd SOF packet ++* @return ++* Frame Number in the following format. ++* bits[13:3] milli-second frame number ++* bits[2:0] micro-frame number ++* @note ++* For full and low speed connections, the microframe number will be zero. ++*****************************************************************************/ ++static inline uint iproc_usbd_last_rx_frame_num(struct iproc_usbd_regs *base) ++{ ++ return((IPROC_USBD_READ(base->dev_status) & IPROC_USBD_REG_STAT_SOF_FRAME_NUM_MASK) >> IPROC_USBD_REG_STAT_SOF_FRAME_NUM_SHIFT); ++} ++ ++/***************************************************************************** ++* @brief Device level interrupt operations ++* @note ++* Use the IPROC_USBD_IRQ_xxx definitions with these routines. These ++* definitions are bit-wise, and allow operations on multiple interrupts ++* by OR'ing the definitions together. ++* DeviceIrqClear(), DeviceIrqDisable(), DeviceIrqEnable() use their mask ++* parameter to operate only on the interrupts set in the mask. E.g. ++* DeviceIrqEnable( DEVICE_IRQ_SET_INTF ); ++* DeviceIrqEnable( DEVICE_IRQ_SET_CFG ); ++* and ++* DeviceIrqEnable( DEVICE_IRQ_SET_INTF | DEVICE_IRQ_SET_CFG ); ++* are equivalent. ++* DeviceIrqMask() returns a mask of all the interrupts that are enabled. ++* DeviceIrqStatus() returns a mask of all the interrupts that have an active status. ++*****************************************************************************/ ++static inline uint iproc_usbd_irq_active(struct iproc_usbd_regs *base) ++{ ++ return(IPROC_USBD_READ(base->dev_irq_status)); ++} ++ ++static inline void iproc_usbd_irq_clear(struct iproc_usbd_regs *base, uint mask) ++{ ++ IPROC_USBD_WRITE(base->dev_irq_status, mask); ++} ++ ++static inline void iproc_usbd_irq_dis(struct iproc_usbd_regs *base, uint mask) ++{ ++ IPROC_USBD_BITS_SET(base->dev_irq_mask, mask); ++} ++ ++static inline void iproc_usbd_irq_en(struct iproc_usbd_regs *base, uint mask) ++{ ++ IPROC_USBD_BITS_CLEAR(base->dev_irq_mask, mask); ++} ++static inline uint iproc_usbd_irq_mask(struct iproc_usbd_regs *base) ++{ ++ return((~IPROC_USBD_READ(base->dev_irq_mask)) & IPROC_USBD_IRQ_ALL); ++} ++ ++/***************************************************************************** ++* @brief Disable / Enable NAK responses for all OUT endpoints. ++*****************************************************************************/ ++static inline void iproc_usbd_nak_response_dis(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_CLEAR(base->dev_ctrl, IPROC_USBD_REG_CTRL_OUT_NAK_ALL_ENABLE); ++} ++ ++static inline void iproc_usbd_nak_response_en(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_SET(base->dev_ctrl, IPROC_USBD_REG_CTRL_OUT_NAK_ALL_ENABLE); ++} ++ ++/***************************************************************************** ++* @brief PHY error detected ++*****************************************************************************/ ++static inline bool iproc_usbd_phy_err_detect(struct iproc_usbd_regs *base) ++{ ++ return(IPROC_USBD_READ(base->dev_status) & IPROC_USBD_REG_STAT_PHY_ERROR ? true : false); ++} ++ ++/***************************************************************************** ++* @brief Remote Wakeup operations. ++* DeviceRemoteWakeupEnable() and DeviceRemoteWakeupDisable() are used to ++* specify device if is going to attempt this. ++* DeviceRemoteWakeupAllowed() indicates if host has enabled this feature. ++* The associated DEVICE_IRQ_REMOTEWAKEUP_DELTA can be used to determine ++* changes to the status of this feature. ++* DeviceRemoteWakeupStart(); delayMsec(1); DeviceRemoteWakeupStop(); is ++* used for controlling the wakeup signalling. ++*****************************************************************************/ ++static inline bool iproc_usbd_wakeup_allow(struct iproc_usbd_regs *base) ++{ ++ return(IPROC_USBD_READ(base->dev_status) & IPROC_USBD_REG_STAT_REMOTE_WAKEUP_ALLOWED ? true : false); ++} ++ ++static inline void iproc_usbd_wakeup_dis(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_CLEAR(base->dev_cfg, IPROC_USBD_REG_CFG_REMOTE_WAKEUP_ENABLE); ++} ++ ++static inline void iproc_usbd_wakeup_en(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_SET(base->dev_cfg, IPROC_USBD_REG_CFG_REMOTE_WAKEUP_ENABLE); ++} ++ ++static inline void iproc_usbd_wakeup_start(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_SET(base->dev_ctrl, IPROC_USBD_REG_CTRL_RESUME_SIGNAL_ENABLE); ++} ++ ++static inline void iproc_usbd_wakeup_stop(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_CLEAR(base->dev_ctrl, IPROC_USBD_REG_CTRL_RESUME_SIGNAL_ENABLE); ++} ++ ++/***************************************************************************** ++* @brief Control whether or not device advertises itself as self-powered. ++*****************************************************************************/ ++static inline void iproc_usbd_self_pwr_dis(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_CLEAR(base->dev_cfg, IPROC_USBD_REG_CFG_SELF_PWR_ENABLE); ++} ++ ++static inline void iproc_usbd_self_pwr_en(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_SET(base->dev_cfg, IPROC_USBD_REG_CFG_SELF_PWR_ENABLE); ++} ++ ++/***************************************************************************** ++* @brief Control whether or not device SET DESCRIPTOR support is enabled. ++* If disabled, STALL will be issued upon receipt of a SET DESCRIPTOR request. ++*****************************************************************************/ ++static inline void iproc_usbd_set_desc_dis(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_CLEAR(base->dev_cfg, IPROC_USBD_REG_CFG_SET_DESCRIPTOR_ENABLE); ++} ++ ++static inline void iproc_usbd_set_desc_en(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_SET(base->dev_cfg, IPROC_USBD_REG_CFG_SET_DESCRIPTOR_ENABLE); ++} ++ ++/***************************************************************************** ++* @brief Device SET configuration or SET interface has completed. ++* If disabled, STALL will be issued upon receipt of a SET DESCRIPTOR request. ++*****************************************************************************/ ++static inline void iproc_usbd_setup_done(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_SET(base->dev_ctrl, IPROC_USBD_REG_CTRL_CSR_DONE); ++} ++ ++/***************************************************************************** ++* @brief Link speed routines. ++* Use the usbDevHw_DEVICE_SPEED_xxx definitions with these routines. These ++* DeviceSpeedRequested() indicates the desired link speed. ++* DeviceSpeedEnumerated() returns the speed negotiated with the host. ++* The associated DEVICE_IRQ_SPEED_ENUM_DONE can be used to determine ++* when speed negotiation has completed. ++*****************************************************************************/ ++static inline uint iproc_usbd_speed_get(struct iproc_usbd_regs *base) ++{ ++ switch(IPROC_USBD_READ(base->dev_status) & IPROC_USBD_REG_STAT_SPD_MASK) { ++ case IPROC_USBD_REG_STAT_SPD_LS: ++ return(IPROC_USBD_SPEED_LOW); ++ ++ case IPROC_USBD_REG_STAT_SPD_HS: ++ return(IPROC_USBD_SPEED_HIGH); ++ ++ case IPROC_USBD_REG_STAT_SPD_FS: ++ case IPROC_USBD_REG_STAT_SPD_FS_48MHZ: ++ return(IPROC_USBD_SPEED_FULL); ++ } ++ ++ return IPROC_USBD_SPEED_FULL; ++} ++ ++static inline void iproc_usbd_speed_req(struct iproc_usbd_regs *base, uint speed) ++{ ++ IPROC_USBD_BITS_CLEAR(base->dev_cfg, IPROC_USBD_REG_CFG_SPD_MASK); ++ ++ switch(speed) { ++ case IPROC_USBD_SPEED_LOW: ++ IPROC_USBD_BITS_SET(base->dev_cfg, IPROC_USBD_REG_CFG_SPD_LS); ++ break; ++ ++ case IPROC_USBD_SPEED_HIGH: ++ IPROC_USBD_BITS_SET(base->dev_cfg, IPROC_USBD_REG_CFG_SPD_HS); ++ break; ++ ++ case IPROC_USBD_SPEED_FULL: ++ default: ++ IPROC_USBD_BITS_SET(base->dev_cfg, IPROC_USBD_REG_CFG_SPD_FS); ++ break; ++ } ++} ++ ++/***************************************************************************** ++* @brief Finalize (terminate) / Initialize Endpoint operations ++* @param num - Endpoint number ++* @param dirn - Endpoint direction. See ENDPT_DIRN_xxx definitions ++* @param dirn - Endpoint type. See ENDPT_TYPE_xxx definitions ++* @param dirn - Endpoint max packet size. ++*****************************************************************************/ ++static inline void iproc_usbd_ep_ops_finish(struct iproc_usbd_regs *base, uint num) ++{ ++} ++ ++static inline void iproc_usbd_ep_ops_init(struct iproc_usbd_regs *base, uint num, uint type, uint dirn, uint maxPktSize) ++{ ++ if ((type == IPROC_USBD_EP_TYPE_CTRL) || (dirn == IPROC_USBD_EP_DIR_OUT)) { ++ IPROC_USBD_WRITE(base->ep_fifo_out[num].ctrl, (type << IPROC_USBD_REG_EP_FIFO_CTRL_TYPE_SHIFT)); ++ IPROC_USBD_WRITE(base->ep_fifo_out[num].status, IPROC_USBD_READ(base->ep_fifo_out[num].status)); ++ IPROC_USBD_WRITE(base->ep_fifo_out[num].size1, 0); ++ IPROC_USBD_WRITE(base->ep_fifo_out[num].size2, ((maxPktSize >> 2) << 16) | maxPktSize); ++#if IPROC_USBD_MULTI_RX_FIFO ++ IPROC_USBD_BITS_SET(base->ep_fifo_out[num].size2, ((maxPktSize + 3) >> 2) << IPROC_USBD_REG_EP_FIFO_SIZE2_OUT_DEPTH_SHIFT)); ++#endif ++ } ++ if ((type == IPROC_USBD_EP_TYPE_CTRL) || (dirn == IPROC_USBD_EP_DIR_IN)) { ++ IPROC_USBD_WRITE(base->ep_fifo_in[num].ctrl, (type << IPROC_USBD_REG_EP_FIFO_CTRL_TYPE_SHIFT)); ++ IPROC_USBD_WRITE(base->ep_fifo_in[num].size2, (maxPktSize << IPROC_USBD_REG_EP_FIFO_SIZE2_PKT_MAX_SHIFT)); ++ IPROC_USBD_WRITE(base->ep_fifo_in[num].size1, (maxPktSize >> 2)); ++ IPROC_USBD_BITS_SET(base->ep_fifo_in[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_IN_FLUSH_ENABLE); ++ IPROC_USBD_BITS_CLEAR(base->ep_fifo_in[num].ctrl, (IPROC_USBD_REG_EP_FIFO_CTRL_NAK_SET | IPROC_USBD_REG_EP_FIFO_CTRL_IN_FLUSH_ENABLE)); ++ } ++ IPROC_USBD_WRITE(base->ep_cfg[num], (num << IPROC_USBD_REG_EP_CFG_FIFO_NUM_SHIFT) | ++ (type << IPROC_USBD_REG_EP_CFG_TYPE_SHIFT) | ++ (maxPktSize << IPROC_USBD_REG_EP_CFG_PKT_MAX_SHIFT) | ++ (dirn == IPROC_USBD_EP_DIR_OUT ? IPROC_USBD_REG_EP_CFG_DIRN_OUT : IPROC_USBD_REG_EP_CFG_DIRN_IN)); ++} ++ ++/***************************************************************************** ++* @brief Endpoint Configuration / Interface / Alternate number operations ++* @param num - Endpoint number ++* @param cfg - Configuration number ++* @param intf - Interface number ++* @param alt - Alternate number ++*****************************************************************************/ ++static inline void iproc_usbd_ep_alt_set(struct iproc_usbd_regs *base, uint num, uint alt) ++{ ++ IPROC_USBD_BITS_MODIFY(base->ep_cfg[num], IPROC_USBD_REG_EP_CFG_ALT_NUM_MASK, (alt << IPROC_USBD_REG_EP_CFG_ALT_NUM_SHIFT)); ++} ++ ++static inline void iproc_usbd_ep_cfg_set(struct iproc_usbd_regs *base, uint num, uint cfg) ++{ ++ IPROC_USBD_BITS_MODIFY(base->ep_cfg[num], IPROC_USBD_REG_EP_CFG_CFG_NUM_MASK, (cfg << IPROC_USBD_REG_EP_CFG_CFG_NUM_SHIFT)); ++} ++ ++static inline void iproc_usbd_ep_intf_set(struct iproc_usbd_regs *base, uint num, uint intf) ++{ ++ IPROC_USBD_BITS_MODIFY(base->ep_cfg[num], IPROC_USBD_REG_EP_CFG_INTF_NUM_MASK, (intf << IPROC_USBD_REG_EP_CFG_INTF_NUM_SHIFT)); ++} ++ ++ ++/***************************************************************************** ++* @brief Endpoint DMA routines ++* @param num - Endpoint number ++* @param addr - physical address of buffer or descriptor ++*****************************************************************************/ ++static inline void iproc_usbd_ep_dma_dis(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == IPROC_USBD_EP_DIR_OUT) { ++#if IPROC_USBD_MULTI_RX_FIFO ++ IPROC_USBD_BITS_CLEAR(base->ep_fifo_out[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_OUT_DMA_ENABLE); ++#else ++ /* ++ * With a single RX FIFO, do not want to do anything, as there might be another OUT capable ++ * endpoint still active and wanting DMA enabled. If theory this should be OK, as long as ++ * the DMA descriptor buffer status fields are the last thing updated before being set to ++ * HOST ready, or the first thing updated when being set to HOST busy. Hopefully no ++ * situations arise such that there's contention with the hardware with doing this. ++ */ ++#endif ++ } else { ++ IPROC_USBD_BITS_CLEAR(base->ep_fifo_in[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_IN_DMA_ENABLE); ++ } ++} ++ ++static inline void iproc_usbd_ep_dma_en(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == IPROC_USBD_EP_DIR_OUT) { ++#if IPROC_USBD_MULTI_RX_FIFO ++ IPROC_USBD_BITS_SET(base->ep_fifo_out[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_OUT_DMA_ENABLE); ++#else ++ IPROC_USBD_BITS_SET(base->dev_ctrl, IPROC_USBD_REG_CTRL_DMA_OUT_ENABLE); ++#endif ++ } else { ++ /* Set the Poll bit in the control register */ ++ IPROC_USBD_BITS_SET(base->ep_fifo_in[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_IN_DMA_ENABLE); ++ } ++} ++ ++static inline void iproc_usbd_ep_dma_buf_addr_set(struct iproc_usbd_regs *base, uint num, uint dirn, void *addr) ++{ ++ if (dirn == IPROC_USBD_EP_DIR_OUT) { ++ IPROC_USBD_WRITE(base->ep_fifo_out[num].buf_addr, (uint)addr); ++ } ++} ++ ++static inline void iproc_usbd_ep_dma_desc_addr_set(struct iproc_usbd_regs *base, uint num, uint dirn, void *addr) ++{ ++ if (dirn == IPROC_USBD_EP_DIR_OUT) { ++ IPROC_USBD_WRITE(base->ep_fifo_out[num].desc_addr, (uint)addr); ++ } ++ else { ++ IPROC_USBD_WRITE(base->ep_fifo_in[num].desc_addr, (uint)addr); ++ } ++} ++ ++/***************************************************************************** ++* @brief Endpoint FIFO routines ++* @param num - Endpoint number ++* @note The flush operation is a state. Once enabled, FIFO contents are discared ++* until disabled. Usually enable upon endpoint termination or error, and ++* then disable once operations are to resume normally. ++*****************************************************************************/ ++static inline bool iproc_usbd_ep_fifo_empty(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == IPROC_USBD_EP_DIR_OUT) { ++#if IPROC_USBD_MULTI_RX_FIFO ++ return(base->ep_fifo_out[num].status & IPROC_USBD_REG_EP_FIFO_STATUS_OUT_FIFO_EMPTY ? true : false); ++#else ++ return(base->dev_status & IPROC_USBD_REG_STAT_OUT_FIFO_EMPTY ? true : false); ++#endif ++ } ++ return(base->ep_fifo_in[num].status & IPROC_USBD_REG_EP_FIFO_STATUS_IN_FIFO_EMPTY ? true : false); ++} ++ ++static inline void iproc_usbd_ep_fifo_flush_dis(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == IPROC_USBD_EP_DIR_OUT) { ++#if IPROC_USBD_MULTI_RX_FIFO ++ IPROC_USBD_BITS_CLEAR(base->ep_fifo_out[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_OUT_FLUSH_ENABLE); ++#else ++ IPROC_USBD_BITS_CLEAR(base->dev_ctrl, IPROC_USBD_REG_CTRL_OUT_FIFO_FLUSH_ENABLE); ++#endif ++ } ++ else { ++ IPROC_USBD_BITS_CLEAR(base->ep_fifo_in[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_IN_FLUSH_ENABLE); ++ } ++} ++ ++static inline void iproc_usbd_ep_fifo_flush_en(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == IPROC_USBD_EP_DIR_OUT) { ++#if IPROC_USBD_MULTI_RX_FIFO ++ IPROC_USBD_BITS_SET(base->ep_fifo_out[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_OUT_FLUSH_ENABLE); ++#else ++ IPROC_USBD_BITS_SET(base->dev_ctrl, IPROC_USBD_REG_CTRL_OUT_FIFO_FLUSH_ENABLE); ++#endif ++ } else { ++ IPROC_USBD_BITS_SET(base->ep_fifo_in[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_IN_FLUSH_ENABLE); ++ } ++} ++ ++/***************************************************************************** ++* @brief Endpoint Frame Number routines ++* @param num - Endpoint number ++* @return Frame number of last packet received on the endpoint, and in the following format. ++* bits[13:3] milli-second frame number ++* bits[2:0] micro-frame number ++* @note Really only applicable to OUT endpoints. IN will always return 0. ++*****************************************************************************/ ++static inline uint iproc_usbd_ep_frame_num(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == IPROC_USBD_EP_DIR_OUT) { ++ return((IPROC_USBD_READ(base->ep_fifo_out[num].size1) & IPROC_USBD_REG_EP_FIFO_SIZE1_OUT_FRAME_NUM_MASK) >> IPROC_USBD_REG_EP_FIFO_SIZE1_OUT_FRAME_NUM_SHIFT); ++ } ++ return(0); ++} ++ ++/***************************************************************************** ++* @brief Endpoint IRQ / status routines ++* @param num - Endpoint number ++* @note ++* Cannot set specific status for Endpoint interrupts. Can only do operations ++* in a global sense. Once an interrupt occurs for an endpoint, the endpoint ++* status has to be checked for the particular type of interrupt that occurred. ++* ++* The iproc_usbd_ep_irq_en() and iproc_usbd_ep_irq_dis() are used for ++* operations on a specific endpoint. These routines may or may not be used in ++* the context of interrupt processing. ++* ++* Use the usbDevHw_EndptIrqListXxx() routines for operations using a bit-wise ++* list of endpoints (bit 0 for endpoint 0, etc.). Typical use would be for ++* interrupt processing. ++* ++* Use the IPROC_USBD_EP_STAT_xxx definitions with the status routines. These ++* definitions are bit-wise, and allow operations on multiple conditions ++* by OR'ing the definitions together. ++*****************************************************************************/ ++static inline void iproc_usbd_ep_irq_clear(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == IPROC_USBD_EP_DIR_OUT) { ++ IPROC_USBD_WRITE(base->ep_irq_status, (1 << num) << IPROC_USBD_REG_EP_INTR_OUT_SHIFT); ++ } else { ++ IPROC_USBD_WRITE(base->ep_irq_status, (1 << num) << IPROC_USBD_REG_EP_INTR_IN_SHIFT); ++ } ++} ++ ++static inline void iproc_usbd_ep_irq_dis(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == IPROC_USBD_EP_DIR_OUT) { ++ IPROC_USBD_BITS_SET(base->ep_irq_mask, ((1 << num) << IPROC_USBD_REG_EP_INTR_OUT_SHIFT)); ++ } else { ++ IPROC_USBD_BITS_SET(base->ep_irq_mask, ((1 << num) << IPROC_USBD_REG_EP_INTR_IN_SHIFT)); ++ } ++} ++ ++static inline void iproc_usbd_ep_irq_en(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == IPROC_USBD_EP_DIR_OUT) { ++ IPROC_USBD_BITS_CLEAR(base->ep_irq_mask, ((1 << num) << IPROC_USBD_REG_EP_INTR_OUT_SHIFT)); ++ } else { ++ IPROC_USBD_BITS_CLEAR(base->ep_irq_mask, ((1 << num) << IPROC_USBD_REG_EP_INTR_IN_SHIFT)); ++ } ++} ++ ++static inline uint iproc_usbd_ep_irq_list_active(struct iproc_usbd_regs *base, uint dirn) ++{ ++ if (dirn == IPROC_USBD_EP_DIR_OUT) { ++ return((IPROC_USBD_READ(base->ep_irq_status) & IPROC_USBD_REG_EP_INTR_OUT_MASK) >> IPROC_USBD_REG_EP_INTR_OUT_SHIFT); ++ } ++ return((IPROC_USBD_READ(base->ep_irq_status) & IPROC_USBD_REG_EP_INTR_IN_MASK) >> IPROC_USBD_REG_EP_INTR_IN_SHIFT); ++} ++ ++static inline void iproc_usbd_ep_irq_list_clear(struct iproc_usbd_regs *base, uint dirn, uint mask) ++{ ++ if (dirn == IPROC_USBD_EP_DIR_OUT) { ++ IPROC_USBD_WRITE(base->ep_irq_status, (mask << IPROC_USBD_REG_EP_INTR_OUT_SHIFT)); /*strat from bit 16 */ ++ } else { ++ IPROC_USBD_WRITE(base->ep_irq_status, (mask << IPROC_USBD_REG_EP_INTR_IN_SHIFT)); /* start from bit 0 */ ++ } ++} ++ ++static inline uint iproc_usbd_ep_stat_active(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == IPROC_USBD_EP_DIR_OUT) { ++ return(IPROC_USBD_READ(base->ep_fifo_out[num].status)); /* End Point Status register */ ++ } ++ return(IPROC_USBD_READ(base->ep_fifo_in[num].status)); ++} ++ ++static inline void iproc_usbd_ep_stat_clear(struct iproc_usbd_regs *base, uint num, uint dirn, uint mask) ++{ ++ if (dirn == IPROC_USBD_EP_DIR_OUT) { ++ IPROC_USBD_WRITE(base->ep_fifo_out[num].status, mask); ++ } else { ++ IPROC_USBD_WRITE(base->ep_fifo_in[num].status, mask); ++ } ++} ++ ++/***************************************************************************** ++* @brief Endpoint NAK routines ++* @param num - Endpoint number ++* @note A NAK response can be enabled by the application by the EndptNakEnable(). ++* The EndptNakInProgress() is used to determine if the controller is ++* currently actively sending NAKs. This may have been a result of the ++* EndptNakEnable() or automatically by the controller under certain ++* conditions. The EndptNakClear() must be used to terminate the NAKs. ++*****************************************************************************/ ++static inline void iproc_usbd_ep_nak_clear(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == IPROC_USBD_EP_DIR_OUT) { ++ IPROC_USBD_BITS_SET(base->ep_fifo_out[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_NAK_CLEAR); ++ } else { ++ IPROC_USBD_BITS_SET(base->ep_fifo_in[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_NAK_CLEAR); ++ } ++} ++ ++static inline void iproc_usbd_ep_nak_en(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == IPROC_USBD_EP_DIR_OUT) { ++ IPROC_USBD_BITS_SET(base->ep_fifo_out[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_NAK_SET); ++ } else { ++ IPROC_USBD_BITS_SET(base->ep_fifo_in[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_NAK_SET); ++ } ++} ++ ++static inline void iproc_usbd_ep_nak_dis(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == IPROC_USBD_EP_DIR_OUT) { ++ IPROC_USBD_BITS_CLEAR(base->ep_fifo_out[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_NAK_SET); ++ } else { ++ IPROC_USBD_BITS_CLEAR(base->ep_fifo_in[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_NAK_SET); ++ } ++} ++ ++static inline bool iproc_usbd_ep_nak_progress(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == IPROC_USBD_EP_DIR_OUT) { ++ return (IPROC_USBD_READ(base->ep_fifo_out[num].ctrl) & IPROC_USBD_REG_EP_FIFO_CTRL_NAK_IN_PROGRESS) ? true : false; ++ } ++ return (IPROC_USBD_READ(base->ep_fifo_in[num].ctrl) & IPROC_USBD_REG_EP_FIFO_CTRL_NAK_IN_PROGRESS) ? true : false; ++} ++ ++/***************************************************************************** ++* @brief Endpoint Stall routines ++* Disable / Enable STALL responses (halt feature) on a given endpoint. ++* @param num - Endpoint number ++*****************************************************************************/ ++static inline void iproc_usbd_ep_stall_dis(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == IPROC_USBD_EP_DIR_OUT) { ++ IPROC_USBD_BITS_CLEAR(base->ep_fifo_out[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_STALL_ENABLE); ++ } else { ++ IPROC_USBD_BITS_CLEAR(base->ep_fifo_in[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_STALL_ENABLE); ++ } ++} ++ ++static inline void iproc_usbd_ep_stall_en(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++#if IPROC_USBD_MULTI_RX_FIFO ++ if (!(IPROC_USBD_READ(base->ep_fifo_out[num].status) & IPROC_USBD_REG_EP_FIFO_STATUS_OUT_FIFO_EMPTY)) ++#else ++ if (!(IPROC_USBD_READ(base->dev_status) & IPROC_USBD_REG_STAT_OUT_FIFO_EMPTY)) ++#endif ++ return; ++ ++ if (dirn == IPROC_USBD_EP_DIR_OUT) { ++ IPROC_USBD_BITS_SET(base->ep_fifo_out[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_STALL_ENABLE); ++ } else { ++ IPROC_USBD_BITS_SET(base->ep_fifo_in[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_STALL_ENABLE); ++ } ++} ++ ++ ++/***************************************************************************** ++* @brief Initialize device controller operations ++*****************************************************************************/ ++static inline void iproc_usbd_ops_init(struct iproc_usbd_regs *base) ++{ ++ int idx; ++ ++ iproc_usbd_dma_dis(base); ++ iproc_usbd_irq_dis(base, IPROC_USBD_IRQ_ALL); ++ iproc_usbd_irq_clear(base, IPROC_USBD_IRQ_ALL); ++ ++ /* @todo Create and use usbDevHw_EndptIrqListDisable?? */ ++ for (idx = 0; idx < IPROC_USBD_EP_CFG_CNT; idx++) { ++ iproc_usbd_ep_irq_dis(base, idx, IPROC_USBD_EP_DIR_IN); ++ iproc_usbd_ep_irq_clear(base, idx, IPROC_USBD_EP_DIR_IN); ++ iproc_usbd_ep_stat_clear(base, idx, IPROC_USBD_EP_DIR_IN, iproc_usbd_ep_stat_active(base, idx, IPROC_USBD_EP_DIR_IN)); ++ ++ iproc_usbd_ep_irq_dis(base, idx, IPROC_USBD_EP_DIR_OUT); ++ iproc_usbd_ep_irq_clear(base, idx, IPROC_USBD_EP_DIR_OUT); ++ iproc_usbd_ep_stat_clear(base, idx, IPROC_USBD_EP_DIR_OUT, iproc_usbd_ep_stat_active(base, idx, IPROC_USBD_EP_DIR_OUT)); ++ } ++ ++ IPROC_USBD_WRITE(base->dev_cfg, (IPROC_USBD_REG_CFG_SET_DESCRIPTOR_ENABLE | ++ IPROC_USBD_REG_CFG_UTMI_8BIT_ENABLE | ++ IPROC_USBD_REG_CFG_CSR_PROGRAM_ENABLE | ++ IPROC_USBD_REG_CFG_SPD_HS)); ++ ++ IPROC_USBD_WRITE(base->dev_ctrl, (IPROC_USBD_REG_CTRL_LE_ENABLE | ++ IPROC_USBD_REG_CTRL_DISCONNECT_ENABLE | ++ IPROC_USBD_REG_CTRL_DMA_MODE_ENABLE | ++ IPROC_USBD_REG_CTRL_DMA_IN_ENABLE | ++ IPROC_USBD_REG_CTRL_DMA_OUT_ENABLE | ++ IPROC_USBD_REG_CTRL_DMA_DESC_UPDATE_ENABLE | ++ IPROC_USBD_REG_CTRL_OUT_NAK_ALL_ENABLE | ++ IPROC_USBD_REG_CTRL_DMA_OUT_THRESHOLD_LEN_MASK | ++ IPROC_USBD_REG_CTRL_DMA_BURST_LEN_MASK | ++#if !IPROC_USBD_MULTI_RX_FIFO ++ IPROC_USBD_REG_CTRL_OUT_FIFO_FLUSH_ENABLE | ++#endif ++ IPROC_USBD_REG_CTRL_DMA_BURST_ENABLE)); ++ ++ IPROC_USBD_WRITE(base->dev_irq_mask, (IPROC_USBD_REG_INTR_BUS_IDLE | ++ IPROC_USBD_REG_INTR_SOF_RX)); ++ IPROC_USBD_WRITE(base->ep_irq_mask,0); ++} ++ ++/***************************************************************************** ++* @brief Disable / Enable USB device ++*****************************************************************************/ ++static inline void iproc_usbd_dis(struct iproc_usbd_idm_regs *idm_base) ++{ ++ /* reset usb device */ ++ IPROC_USBD_BITS_SET(idm_base->reset_ctrl, IPROC_USB2D_IDM_REG_RESET_CTRL_RESET); ++ ++ /* disable usb device clock */ ++ IPROC_USBD_BITS_CLEAR(idm_base->io_ctrl, IPROC_USB2D_IDM_REG_IO_CTRL_DIRECT_CLK_ENABLE); ++ mdelay(10); ++} ++ ++static inline void iproc_usbd_en(struct iproc_usbd_idm_regs *idm_base) ++{ ++ /* enable usb device clock */ ++ IPROC_USBD_BITS_SET(idm_base->io_ctrl, IPROC_USB2D_IDM_REG_IO_CTRL_DIRECT_CLK_ENABLE); ++ mdelay(10); ++ ++ /* get usb device out of reset */ ++ IPROC_USBD_BITS_CLEAR(idm_base->reset_ctrl, IPROC_USB2D_IDM_REG_RESET_CTRL_RESET); ++ mdelay(100); ++} ++ ++ ++ ++#endif /* _USBD_REGS_H_ */ +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig +--- a/drivers/usb/host/Kconfig 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/usb/host/Kconfig 2017-11-09 17:54:01.760430000 +0800 +@@ -298,6 +298,13 @@ config USB_EHCI_HCD_PLATFORM + + If unsure, say N. + ++config USB_EHCI_XGS_IPROC ++ bool "BRCM XGS iProc EHCI patch" ++ depends on (ARCH_XGS_IPROC && USB_EHCI_HCD_PLATFORM) ++ default n ++ ---help--- ++ This option is for BRCM XGS iProc EHCI patch ++ + config USB_OCTEON_EHCI + bool "Octeon on-chip EHCI support (DEPRECATED)" + depends on CAVIUM_OCTEON_SOC +@@ -561,6 +568,13 @@ config USB_OHCI_HCD_PLATFORM + + If unsure, say N. + ++config USB_OHCI_XGS_IPROC ++ bool "BRCM XGS iProc OHCI patch" ++ depends on (ARCH_XGS_IPROC && USB_OHCI_HCD_PLATFORM) ++ default n ++ ---help--- ++ This option is for BRCM XGS iProc OHCI patch ++ + config USB_OCTEON_OHCI + bool "Octeon on-chip OHCI support (DEPRECATED)" + depends on CAVIUM_OCTEON_SOC +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c +--- a/drivers/usb/host/ehci-platform.c 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/usb/host/ehci-platform.c 2017-11-09 17:54:01.791421000 +0800 +@@ -41,6 +41,14 @@ + #define EHCI_MAX_CLKS 3 + #define hcd_to_ehci_priv(h) ((struct ehci_platform_priv *)hcd_to_ehci(h)->priv) + ++ ++#ifdef CONFIG_USB_EHCI_XGS_IPROC ++#include ++#include ++ ++#define BCM_USB_FIFO_THRESHOLD 0x00800040 ++#endif /* CONFIG_USB_EHCI_XGS_IPROC */ ++ + struct ehci_platform_priv { + struct clk *clks[EHCI_MAX_CLKS]; + struct reset_control *rst; +@@ -150,10 +158,24 @@ static int ehci_platform_probe(struct pl + struct ehci_platform_priv *priv; + struct ehci_hcd *ehci; + int err, irq, phy_num, clk = 0; ++#ifdef CONFIG_USB_EHCI_XGS_IPROC ++ struct usb_phy *phy; ++#endif /* CONFIG_USB_EHCI_XGS_IPROC */ + + if (usb_disabled()) + return -ENODEV; + ++#ifdef CONFIG_USB_EHCI_XGS_IPROC ++ phy = devm_usb_get_phy_by_phandle(&dev->dev, "usb-phy", 0); ++ if (IS_ERR(phy)) { ++ dev_err(&dev->dev, "unable to find transceiver\n"); ++ return PTR_ERR(phy); ++ } ++ ++ if (phy->flags != IPROC_USB_MODE_HOST) ++ return -ENODEV; ++#endif ++ + /* + * Use reasonable defaults so platforms don't have to provide these + * with DT probing on ARM. +@@ -292,6 +314,9 @@ static int ehci_platform_probe(struct pl + goto err_power; + + device_wakeup_enable(hcd->self.controller); ++#ifdef CONFIG_USB_EHCI_XGS_IPROC ++ ehci_writel(ehci, BCM_USB_FIFO_THRESHOLD, &ehci->regs->reserved4[6]); ++#endif + platform_set_drvdata(dev, hcd); + + return err; +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c +--- a/drivers/usb/host/ohci-platform.c 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/usb/host/ohci-platform.c 2017-11-09 17:54:01.874447000 +0800 +@@ -35,6 +35,14 @@ + #define OHCI_MAX_CLKS 3 + #define hcd_to_ohci_priv(h) ((struct ohci_platform_priv *)hcd_to_ohci(h)->priv) + ++#ifdef CONFIG_USB_OHCI_XGS_IPROC ++#include ++#include ++ ++#define UHCRHDA_REG_OFFSET 0x48 ++#define UHCRHDA_OCPM (1 << 11) ++#endif ++ + struct ohci_platform_priv { + struct clk *clks[OHCI_MAX_CLKS]; + struct reset_control *rst; +@@ -118,10 +126,24 @@ static int ohci_platform_probe(struct pl + struct ohci_platform_priv *priv; + struct ohci_hcd *ohci; + int err, irq, phy_num, clk = 0; ++#ifdef CONFIG_USB_OHCI_XGS_IPROC ++ struct usb_phy *phy; ++#endif /* CONFIG_USB_OHCI_XGS_IPROC */ + + if (usb_disabled()) + return -ENODEV; + ++#ifdef CONFIG_USB_OHCI_XGS_IPROC ++ phy = devm_usb_get_phy_by_phandle(&dev->dev, "usb-phy", 0); ++ if (IS_ERR(phy)) { ++ dev_err(&dev->dev, "unable to find transceiver\n"); ++ return PTR_ERR(phy); ++ } ++ ++ if (phy->flags != IPROC_USB_MODE_HOST) ++ return -ENODEV; ++#endif /* CONFIG_USB_OHCI_XGS_IPROC */ ++ + /* + * Use reasonable defaults so platforms don't have to provide these + * with DT probing on ARM. +@@ -251,6 +273,12 @@ static int ohci_platform_probe(struct pl + hcd->rsrc_start = res_mem->start; + hcd->rsrc_len = resource_size(res_mem); + ++#ifdef CONFIG_USB_OHCI_XGS_IPROC ++#if defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_HR3) || defined(CONFIG_MACH_GH2) ++ writel(readl(hcd->regs + UHCRHDA_REG_OFFSET) | UHCRHDA_OCPM, hcd->regs + UHCRHDA_REG_OFFSET); ++#endif ++#endif ++ + err = usb_add_hcd(hcd, irq, IRQF_SHARED); + if (err) + goto err_power; +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig +--- a/drivers/usb/phy/Kconfig 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/usb/phy/Kconfig 2017-11-09 17:54:02.191425000 +0800 +@@ -213,4 +213,11 @@ config USB_ULPI_VIEWPORT + Provides read/write operations to the ULPI phy register set for + controllers with a viewport register (e.g. Chipidea/ARC controllers). + ++config USBPHY_XGS_IPROC ++ tristate "BRCM iProc USB PHY" ++ depends on ARCH_XGS_IPROC ++ select USB_PHY ++ help ++ BRCM iProc USB PHY driver ++ + endmenu +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile +--- a/drivers/usb/phy/Makefile 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/usb/phy/Makefile 2017-11-09 17:54:02.191443000 +0800 +@@ -27,3 +27,4 @@ obj-$(CONFIG_USB_RCAR_PHY) += phy-rcar- + obj-$(CONFIG_USB_ULPI) += phy-ulpi.o + obj-$(CONFIG_USB_ULPI_VIEWPORT) += phy-ulpi-viewport.o + obj-$(CONFIG_KEYSTONE_USB_PHY) += phy-keystone.o ++obj-$(CONFIG_USBPHY_XGS_IPROC) += phy-xgs-iproc.o +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/usb/phy/phy-xgs-iproc.c b/drivers/usb/phy/phy-xgs-iproc.c +--- a/drivers/usb/phy/phy-xgs-iproc.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/usb/phy/phy-xgs-iproc.c 2017-11-09 17:54:02.236439000 +0800 +@@ -0,0 +1,745 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++#define USB2D_IDM_IDM_IO_CONTROL_DIRECT_ADDR(base) (base + 0x408) ++#define USB2D_IDM_IDM_RESET_CONTROL_ADDR(base) (base + 0x800) ++#define IPROC_WRAP_MISC_STATUS__USBPHY_PLL_LOCK 1 ++#define USB2D_IDM_IDM_RESET_CONTROL__RESET 0 ++#define USB2D_IDM_IDM_IO_CONTROL_DIRECT__clk_enable 0 ++ ++#if defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) ++ ++#define IPROC_CCB_MDIO_MII_CTRL_ADDR(base) (base + 0x0) ++#define IPROC_CCB_MDIO_MII_DATA_ADDR(base) (base + 0x4) ++#define IPROC_CCB_MDIO_COMPATIBLE "brcm,iproc-ccb-mdio" ++ ++#if defined(CONFIG_MACH_HX4) ++#define IPROC_WRAP_IPROC_XGPLL_CTRL_0_ADDR(base) (base + 0x1c) ++#define IPROC_WRAP_IPROC_XGPLL_CTRL_4_ADDR(base) (base + 0x2c) ++#define IPROC_WRAP_USBPHY_CTRL_ADDR(base) (base + 0x34) ++#define IPROC_WRAP_MISC_STATUS_ADDR(base) (base + 0x38) ++#define IPROC_CLK_NDIV_40 0x80 ++#define IPROC_CLK_NDIV_20 0x8C ++#define USB_CLK_NDIV_MASK 0xFE7FFE00 ++#define USB_CLK_PLL_RESET_MASK 0xFF7FFE00 ++#define USB_CLK_PHY_RESET_MASK 0xFFFFFE00 ++#define USB_CLK_NDIV_40 0x30 ++#define USB_CLK_NDIV_20 0x60 ++#define IPROC_WRAP_IPROC_XGPLL_CTRL_4__NDIV_INT_R 0 ++#define IPROC_WRAP_IPROC_XGPLL_CTRL_4__NDIV_INT_WIDTH 8 ++#define IPROC_WRAP_IPROC_XGPLL_CTRL_0__CH3_MDIV_R 8 ++#define IPROC_WRAP_IPROC_XGPLL_CTRL_0__CH3_MDIV_WIDTH 8 ++#else ++#define IPROC_DDR_PLL_CTRL_REGISTER_3_ADDR(base) (base + 0x0c) ++#define IPROC_DDR_PLL_CTRL_REGISTER_5_ADDR(base) (base + 0x14) ++#define IPROC_WRAP_USBPHY_CTRL_ADDR(base) (base + 0x20) ++#define IPROC_WRAP_MISC_STATUS_ADDR(base) (base + 0x28) ++#define IPROC_DDR_PLL_CTRL_REGISTER_3__NDIV_INT_R 0 ++#define IPROC_DDR_PLL_CTRL_REGISTER_3__NDIV_INT_WIDTH 10 ++#define IPROC_DDR_PLL_CTRL_REGISTER_5__CH1_MDIV_R 0 ++#define IPROC_DDR_PLL_CTRL_REGISTER_5__CH1_MDIV_WIDTH 8 ++#endif /* defined(CONFIG_MACH_HX4) */ ++ ++#else /* defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) */ ++ ++#define IPROC_WRAP_USBPHY_CTRL_0__PHY_IDDQ 26 ++#define IPROC_WRAP_USBPHY_CTRL_0__PLL_RESETB 25 ++#define IPROC_WRAP_USBPHY_CTRL_0__RESETB 24 ++#define IPROC_WRAP_USBPHY_CTRL_2__PHY_ISO 17 ++#define IPROC_WRAP_USBPHY_CTRL_2__P1CTL_B0 0 ++#define IPROC_WRAP_USBPHY_CTRL_2__P1CTL_B11 11 ++ ++#if defined(CONFIG_MACH_SB2) ++#define IPROC_WRAP_USBPHY_CTRL_0_ADDR(base) (base + 0x28) ++#define IPROC_WRAP_USBPHY_CTRL_2_ADDR(base) (base + 0x30) ++#define IPROC_WRAP_MISC_STATUS_ADDR(base) (base + 0x44) ++#define IPROC_WRAP_TOP_STRAP_CTRL_ADDR(base) (base + 0x70) ++#define IPROC_WRAP_TOP_STRAP_CTRL__USB_DEVICE 10 ++ ++#elif defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_HR3) || \ ++ defined(CONFIG_MACH_GH2) ++#define IPROC_WRAP_USBPHY_CTRL_0_ADDR(base) (base + 0x44) ++#define IPROC_WRAP_USBPHY_CTRL_2_ADDR(base) (base + 0x4c) ++#define IPROC_WRAP_MISC_STATUS_ADDR(base) (base + 0x58) ++#define IPROC_WRAP_TOP_STRAP_STATUS_ADDR(base) (base + 0xa4) ++#define IPROC_WRAP_TOP_STRAP_STATUS__USB2_SEL 17 ++#if defined(CONFIG_MACH_GH2) ++#define USBH_Utmi_p0Ctl(base) (base + 0x10) ++static void __iomem *USBH_Utmi_base = NULL; ++#endif /* defined(CONFIG_MACH_GH2) */ ++#endif ++ ++#endif /* defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) */ ++ ++struct iproc_usb_priv { ++ struct usb_phy phy; ++ struct device *dev; ++ struct device_node *dn; ++ void __iomem *wrap_base; ++ void __iomem *idm_base; ++ uint usb_mode; ++}; ++ ++extern void __iomem *get_iproc_wrap_ctrl_base(void); ++ ++/*************************************************************************** ++**************************************************************************** ++***************************************************************************/ ++static const struct of_device_id xgs_iproc_usb_phy_dt_ids[] = { ++ { .compatible = "brcm,usb-phy,hx4", }, ++ { .compatible = "brcm,usb-phy,kt2", }, ++ { .compatible = "brcm,usb-phy,gh", }, ++ { .compatible = "brcm,usb-phy,sb2", }, ++ { .compatible = "brcm,usb-phy,hr3", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, xgs_iproc_usb_phy_dt_ids); ++ ++ ++static int xgs_iproc_usb_phy_mode(struct iproc_usb_priv *iproc_usb_data) ++{ ++ void __iomem *wrap_base = iproc_usb_data->wrap_base; ++ struct device *dev = iproc_usb_data->dev; ++ int usb_mode = IPROC_USB_MODE_HOST; ++ ulong val; ++#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) ++ int gpio_pin, ret; ++#endif /* (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) */ ++ ++ if (!wrap_base) { ++ return -EINVAL; ++ } ++ ++#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) ++ /* gpio pin 4 to control host/device mode */ ++ gpio_pin = of_get_named_gpio(dev->of_node, "usbdev-gpio", 0); ++ ++ if (gpio_pin < 0) { ++ dev_warn(dev, "No gpio pin set for USB device detection(default to 4)\n"); ++ gpio_pin = 4; ++ } ++ ++ ret = gpio_request(gpio_pin, "usbdev-gpio"); ++ if (ret != 0) { ++ dev_err(dev, "request gpio #%d error.\n", gpio_pin); ++ return ret; ++ } ++ ++ val = __gpio_get_value(gpio_pin); ++ ++ gpio_free(gpio_pin); ++ ++ if (val & 1) { ++ usb_mode = IPROC_USB_MODE_DEVICE; ++ } ++#elif defined(CONFIG_MACH_SB2) ++ /* u-boot enable this bit to indicate usb in host mode */ ++ val = readl_relaxed(IPROC_WRAP_TOP_STRAP_CTRL_ADDR(wrap_base)); ++ if (!(val & (1 << IPROC_WRAP_TOP_STRAP_CTRL__USB_DEVICE))) { ++ usb_mode = IPROC_USB_MODE_DEVICE; ++ } ++#else ++ /* u-boot enable this bit to indicate usb in host mode */ ++ val = readl_relaxed(IPROC_WRAP_TOP_STRAP_STATUS_ADDR(wrap_base)); ++ if (!(val & (1 << IPROC_WRAP_TOP_STRAP_STATUS__USB2_SEL))) { ++ usb_mode = IPROC_USB_MODE_DEVICE; ++ } ++#endif ++ ++ dev_info(dev, "usb mode: %s\n", (usb_mode == IPROC_USB_MODE_DEVICE) ? "DEVICE" : "HOST"); ++ ++ return usb_mode; ++} ++ ++#if (defined (CONFIG_MACH_HX4) || defined (CONFIG_MACH_KT2)) ++/* Returns USB PHY PLL ref clock in MHz */ ++static uint _get_usb_clk(void __iomem *wrap_base) ++{ ++ uint ndiv, mdiv, refclk; ++ ulong val; ++ ++#if defined(CONFIG_MACH_HX4) ++ val = readl_relaxed(IPROC_WRAP_IPROC_XGPLL_CTRL_4_ADDR(wrap_base)); ++ ndiv = ((val >> IPROC_WRAP_IPROC_XGPLL_CTRL_4__NDIV_INT_R) & ++ ~(0xFFFFFFFF << IPROC_WRAP_IPROC_XGPLL_CTRL_4__NDIV_INT_WIDTH)); ++ ++ val = readl_relaxed(IPROC_WRAP_IPROC_XGPLL_CTRL_0_ADDR(wrap_base)); ++ mdiv = ((val >> IPROC_WRAP_IPROC_XGPLL_CTRL_0__CH3_MDIV_R) & ++ ~(0xFFFFFFFF << IPROC_WRAP_IPROC_XGPLL_CTRL_0__CH3_MDIV_WIDTH)); ++#else ++ val = readl_relaxed(IPROC_DDR_PLL_CTRL_REGISTER_3_ADDR(wrap_base)); ++ ndiv = ((val >> IPROC_DDR_PLL_CTRL_REGISTER_3__NDIV_INT_R) & ++ ~(0xFFFFFFFF << IPROC_DDR_PLL_CTRL_REGISTER_3__NDIV_INT_WIDTH)); ++ ++ /* read channel 1 mdiv */ ++ val = readl_relaxed(IPROC_DDR_PLL_CTRL_REGISTER_5_ADDR(wrap_base)); ++ mdiv = ((val >> IPROC_DDR_PLL_CTRL_REGISTER_5__CH1_MDIV_R) & ++ ~(0xFFFFFFFF << IPROC_DDR_PLL_CTRL_REGISTER_5__CH1_MDIV_WIDTH)); ++#endif ++ ++ refclk = (25 * ndiv) / mdiv; ++ ++ return refclk; ++} ++#endif /* (defined (CONFIG_MACH_HX4) || defined (CONFIG_MACH_KT2)) */ ++ ++static int iproc_usb_phy_hx4_config(struct iproc_usb_priv *iproc_usb_data) ++{ ++#if (defined (CONFIG_MACH_HX4) || defined (CONFIG_MACH_KT2)) ++ void __iomem *wrap_base = iproc_usb_data->wrap_base; ++ void __iomem *ccb_mdio_base = NULL; ++ struct device_node *np; ++ ulong ndiv, precmd, miicmd, miidata; ++ ulong val, mask; ++ uint count = 0; ++ ++ if (!wrap_base) ++ return -EINVAL; ++ ++ if (iproc_usb_data->usb_mode == IPROC_USB_MODE_DEVICE) { ++ np = of_find_compatible_node(NULL, NULL, IPROC_CCB_MDIO_COMPATIBLE); ++ if (!np) { ++ printk(KERN_ERR "Failed to find CCB MDIO defined in DT\n"); ++ return -ENODEV; ++ } ++ ++ ccb_mdio_base = of_iomap(np, 0); ++ if (!ccb_mdio_base) { ++ printk(KERN_ERR "Unable to iomap CCB MDIO base address\n"); ++ return -ENXIO; ++ } ++ ++ ndiv = 1920 / _get_usb_clk(wrap_base); ++ ++ /* Construct precmd with Start Bit, PHY address and turnaround time */ ++ /* SB | PA | TA */ ++ precmd = 1 << 30 | 6 << 23 | 2 << 16; ++ ++ /* Connect MDIO interface to onchip PHY */ ++ writel_relaxed(0x9A, IPROC_CCB_MDIO_MII_CTRL_ADDR(ccb_mdio_base)); ++ mdelay(10); ++ ++ /* Program NDIV and PDIV into 0x1C register */ ++ miicmd = precmd | (0x1 << 28) | (0x1C << 18); ++ miidata = 1 << 12 | ndiv; ++ /* 0x53721040 */ ++ writel_relaxed(miicmd | miidata, IPROC_CCB_MDIO_MII_DATA_ADDR(ccb_mdio_base)); ++ mdelay(10); ++ ++ /* Program other PLL parameters into 0x1D register, disable suspend and put PHY into reset */ ++ miicmd = precmd | (0x1 << 28) | (0x1D << 18); ++ miidata = 1 << 13 | 3 << 8 | 3 << 4 | 0xa; ++ /* 0x5376233a */ ++ writel_relaxed(miicmd | miidata, IPROC_CCB_MDIO_MII_DATA_ADDR(ccb_mdio_base)); ++ mdelay(10); ++ ++ /* Program register 0x15, USB device mode set and get PHY out of reset */ ++ miicmd = precmd | (0x1 << 28) | (0x15 << 18); ++ miidata = 1 << 2 | 1 << 1; ++ /* 0x53560006 */ ++ writel_relaxed(miicmd | miidata, IPROC_CCB_MDIO_MII_DATA_ADDR(ccb_mdio_base)); ++ mdelay(10); ++ ++ /* Program register 0x19, set mdio mode */ ++ miicmd = precmd | (0x1 << 28) | (0x19 << 18); ++ miidata = 1 << 7; ++ /* 0x53660080 */ ++ writel_relaxed(miicmd | miidata, IPROC_CCB_MDIO_MII_DATA_ADDR(ccb_mdio_base)); ++ mdelay(10); ++ ++ /* get the PLL out of reset */ ++ miicmd = precmd | (0x2 << 28) | (0x1D << 18); ++ miidata = 0; ++ writel_relaxed(miicmd | miidata, IPROC_CCB_MDIO_MII_DATA_ADDR(ccb_mdio_base)); ++ mdelay(10); ++ miidata = readl_relaxed(IPROC_CCB_MDIO_MII_DATA_ADDR(ccb_mdio_base)); ++ miicmd = precmd | (0x1 << 28) | (0x1D << 18); ++ miidata |= (1 << 12); ++ /* 0x5376333a */ ++ writel_relaxed(miicmd | miidata, IPROC_CCB_MDIO_MII_DATA_ADDR(ccb_mdio_base)); ++ mdelay(10); ++ ++ if (ccb_mdio_base) { ++ iounmap(ccb_mdio_base); ++ ccb_mdio_base = NULL; ++ } ++ } else { ++ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_ADDR(wrap_base)); ++ val |= 0x01000000; /* 24:PLL_RESETB = 1 */ ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_ADDR(wrap_base)); ++ ++ mdelay(20); ++ ++ /* check pll_lock */ ++ mask = (1 << IPROC_WRAP_MISC_STATUS__USBPHY_PLL_LOCK); ++ do { ++ val = readl_relaxed(IPROC_WRAP_MISC_STATUS_ADDR(wrap_base)); ++ if ((val & mask) == mask) { ++ break; ++ } else { ++ udelay(10); ++ count ++; ++ } ++ } while(count <= 10); ++ if (count > 10) { ++ printk(KERN_WARNING "%s : PLL not lock! IPROC_WRAP_MISC_STATUS = 0x%08lx\n", ++ __FUNCTION__, val); ++ } ++ ++ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_ADDR(wrap_base)); ++ val &= ~0x00800000; /* 23:RESETB = 0 */ ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_ADDR(wrap_base)); ++ mdelay(100); ++ ++#if defined(CONFIG_MACH_HX4) ++ val = readl_relaxed(IPROC_WRAP_IPROC_XGPLL_CTRL_4_ADDR(wrap_base)); ++ ndiv = ((val >> IPROC_WRAP_IPROC_XGPLL_CTRL_4__NDIV_INT_R) & ++ ~(0xFFFFFFFF << IPROC_WRAP_IPROC_XGPLL_CTRL_4__NDIV_INT_WIDTH)); ++ if (ndiv == IPROC_CLK_NDIV_40) { ++ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_ADDR(wrap_base)); ++ val = (val & USB_CLK_NDIV_MASK) | USB_CLK_NDIV_40; ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_ADDR(wrap_base)); ++ udelay(10); ++ val = (val & USB_CLK_PLL_RESET_MASK) | USB_CLK_NDIV_40; ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_ADDR(wrap_base)); ++ udelay(10); ++ val = (val & USB_CLK_PHY_RESET_MASK) | USB_CLK_NDIV_40; ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_ADDR(wrap_base)); ++ udelay(10); ++ } else if (ndiv == IPROC_CLK_NDIV_20) { ++ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_ADDR(wrap_base)); ++ val = (val & USB_CLK_NDIV_MASK) | USB_CLK_NDIV_20; ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_ADDR(wrap_base)); ++ udelay(10); ++ val = (val & USB_CLK_PLL_RESET_MASK) | USB_CLK_NDIV_20; ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_ADDR(wrap_base)); ++ udelay(10); ++ val = (val & USB_CLK_PHY_RESET_MASK) | USB_CLK_NDIV_20; ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_ADDR(wrap_base)); ++ udelay(10); ++ } ++#endif /* CONFIG_MACH_HX4 */ ++ ++ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_ADDR(wrap_base)); ++ val |= 0x00800000; /* 23:RESETB = 1 */ ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_ADDR(wrap_base)); ++ udelay(100); ++ } ++#endif /* (defined (CONFIG_MACH_HX4) || defined (CONFIG_MACH_KT2)) */ ++ ++ return 0; ++} ++ ++static int iproc_usb_phy_sb2_config(struct iproc_usb_priv *iproc_usb_data) ++{ ++#if defined(CONFIG_MACH_SB2) ++ void __iomem *wrap_base = iproc_usb_data->wrap_base; ++ ulong val, mask, count = 0; ++ ++ if (!wrap_base) { ++ return -EINVAL; ++ } ++ ++ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val |= 0x0c000000; /* 27:PHY_ISO & 26:PLL_SUSPEND_EN = 1 */ ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val &= ~0x03000000; /* 25:PLL_RESETB & 24:RESETB = 0 */ ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ ++ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ val &= ~0x03000000; /* 25:AFE_BG_PWRDWNB & 24:AFE_LDO_PWRDWNB = 0 */ ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ udelay(10); ++ val |= 0x02000000; /* 25:AFE_BG_PWRDWNB = 1 */ ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ udelay(150); ++ val |= 0x01000000; /* 24:AFE_LDO_PWRDWNB = 1 */ ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ udelay(160); ++ ++ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val &= ~0x08000000; /* 27:PHY_ISO = 0 */ ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ udelay(20); ++ val |= 0x02000000; /* 25:PLL_RESETB = 1 */ ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ ++ mdelay(20); ++ ++ /* check pll_lock */ ++ mask = (1 << IPROC_WRAP_MISC_STATUS__USBPHY_PLL_LOCK); ++ do { ++ val = readl_relaxed(IPROC_WRAP_MISC_STATUS_ADDR(wrap_base)); ++ if ((val & mask) == mask) { ++ break; ++ } else { ++ udelay(10); ++ count ++; ++ } ++ } while(count <= 10); ++ ++ if (count > 10) ++ printk(KERN_WARNING "%s : PLL not lock! IPROC_WRAP_MISC_STATUS = 0x%08lx\n", ++ __FUNCTION__, val); ++ ++ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val |= 0x01000000; /* 24:RESETB = 1 */ ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ udelay(2); ++#endif /* defined(CONFIG_MACH_SB2) */ ++ ++ return 0; ++} ++ ++static int iproc_usb_phy_gh_config(struct iproc_usb_priv *iproc_usb_data) ++{ ++#if defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_HR3) || \ ++ defined (CONFIG_MACH_GH2) ++ void __iomem *wrap_base = iproc_usb_data->wrap_base; ++ ulong val, mask, count = 0; ++ ++ if (!wrap_base) ++ return -EINVAL; ++ ++#if !defined(CONFIG_MACH_GH2) ++ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ val |= (1 << IPROC_WRAP_USBPHY_CTRL_2__PHY_ISO); ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ ++ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val |= (1 << IPROC_WRAP_USBPHY_CTRL_0__PHY_IDDQ); ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ ++ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ val |= (1 << IPROC_WRAP_USBPHY_CTRL_2__P1CTL_B0); ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ ++ /* set phy_resetb to 0, pll_resetb to 0 */ ++ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val &= ~(1 << IPROC_WRAP_USBPHY_CTRL_0__RESETB); ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ ++ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val &= ~(1 << IPROC_WRAP_USBPHY_CTRL_0__PLL_RESETB); ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ ++ /* set p1ctl[11] to 0 */ ++ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ val &= ~(1 << IPROC_WRAP_USBPHY_CTRL_2__P1CTL_B11); ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ ++ /* set phy_iso to 0 */ ++ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ val &= ~(1 << IPROC_WRAP_USBPHY_CTRL_2__PHY_ISO); ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ ++ /* set phy_iddq to 0 */ ++ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val &= ~(1 << IPROC_WRAP_USBPHY_CTRL_0__PHY_IDDQ); ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ ++ mdelay(1); ++ ++ /* set pll_resetb to 1, phy_resetb to 1 */ ++ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val |= (1 << IPROC_WRAP_USBPHY_CTRL_0__PLL_RESETB); ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ ++ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val |= (1 << IPROC_WRAP_USBPHY_CTRL_0__RESETB); ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++#else /* !defined(CONFIG_MACH_GH2) */ ++ /* This value is from the designer to set Internal Power Sequence Mode */ ++ val = readl_relaxed(IPROC_WRAP_TOP_STRAP_STATUS_ADDR(wrap_base)); ++ if (!(val & (1 << IPROC_WRAP_TOP_STRAP_STATUS__USB2_SEL))) { ++ /* device mode */ ++ writel_relaxed(0x0806, IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ } else { ++ /* host mode */ ++ writel_relaxed(0x0802, USBH_Utmi_p0Ctl(USBH_Utmi_base)); ++ } ++#endif /* !defined(CONFIG_MACH_GH2) */ ++ mdelay(20); ++ ++ /* check pll_lock */ ++ mask = (1 << IPROC_WRAP_MISC_STATUS__USBPHY_PLL_LOCK); ++ do { ++ val = readl_relaxed(IPROC_WRAP_MISC_STATUS_ADDR(wrap_base)); ++ if ((val & mask) == mask) { ++ break; ++ } else { ++ udelay(10); ++ count ++; ++ } ++ } while(count <= 10); ++ ++ if (count > 10) { ++ printk(KERN_WARNING "%s : PLL not lock! IPROC_WRAP_MISC_STATUS = 0x%08lx\n", ++ __FUNCTION__, val); ++ } ++ ++#if !defined(CONFIG_MACH_GH2) ++ /* set non_drving to 0 */ ++ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ val &= ~(1 << IPROC_WRAP_USBPHY_CTRL_2__P1CTL_B0); ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ ++ /* set p1ctl[11] to 1 */ ++ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ val |= (1 << IPROC_WRAP_USBPHY_CTRL_2__P1CTL_B11); ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++#endif /* !defined(CONFIG_MACH_GH2) */ ++#endif /* defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_HR3) || defined (CONFI ++G_MACH_GH2) */ ++ ++ return 0; ++} ++ ++static int iproc_usb_phy_init(struct usb_phy *phy) ++{ ++ struct iproc_usb_priv *iproc_usb_data = container_of(phy, struct iproc_usb_priv, phy); ++ struct device *dev = iproc_usb_data->dev; ++ const struct of_device_id *match; ++ int ret = 0; ++ uint val; ++ ++ if (!iproc_usb_data->wrap_base || !iproc_usb_data->idm_base) { ++ return -EINVAL; ++ } ++ ++ match = of_match_device(xgs_iproc_usb_phy_dt_ids, dev); ++ if (!match) { ++ dev_err(dev, "failed to find USB PHY in DT\n"); ++ return -ENODEV; ++ } ++ ++ /* Put USBD controller into reset state and disable clock via IDM registers */ ++ val = readl_relaxed(USB2D_IDM_IDM_RESET_CONTROL_ADDR(iproc_usb_data->idm_base)); ++ val |= (1 << USB2D_IDM_IDM_RESET_CONTROL__RESET); ++ writel_relaxed(val, USB2D_IDM_IDM_RESET_CONTROL_ADDR(iproc_usb_data->idm_base)); ++ ++ val = readl_relaxed(USB2D_IDM_IDM_IO_CONTROL_DIRECT_ADDR(iproc_usb_data->idm_base)); ++ val &= ~(1 << USB2D_IDM_IDM_IO_CONTROL_DIRECT__clk_enable); ++ writel_relaxed(val, USB2D_IDM_IDM_IO_CONTROL_DIRECT_ADDR(iproc_usb_data->idm_base)); ++ ++ if (strstr(match->compatible, "hx4") || ++ strstr(match->compatible, "kt2")) ++ ret = iproc_usb_phy_hx4_config(iproc_usb_data); ++ else if (strstr(match->compatible, "sb2")) ++ ret = iproc_usb_phy_sb2_config(iproc_usb_data); ++#if !defined(CONFIG_MACH_GH2) ++ else ++ ret = iproc_usb_phy_gh_config(iproc_usb_data); ++#endif ++ ++ /* Enable clock to USBD and get the USBD out of reset */ ++ val = readl_relaxed(USB2D_IDM_IDM_IO_CONTROL_DIRECT_ADDR(iproc_usb_data->idm_base)); ++ val |= (1 << USB2D_IDM_IDM_IO_CONTROL_DIRECT__clk_enable); ++ writel_relaxed(val, USB2D_IDM_IDM_IO_CONTROL_DIRECT_ADDR(iproc_usb_data->idm_base)); ++ ++ mdelay(10); ++ val = readl_relaxed(USB2D_IDM_IDM_RESET_CONTROL_ADDR(iproc_usb_data->idm_base)); ++ val &= ~(1 << USB2D_IDM_IDM_RESET_CONTROL__RESET); ++ writel_relaxed(val, USB2D_IDM_IDM_RESET_CONTROL_ADDR(iproc_usb_data->idm_base)); ++ ++#if defined(CONFIG_MACH_GH2) ++ /* In GH2, it must init PHY after RESET */ ++ mdelay(100); ++ ret = iproc_usb_phy_gh_config(iproc_usb_data); ++#endif ++ ++ return ret; ++} ++ ++static int xgs_iproc_usb_phy_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct device_node *dn = pdev->dev.of_node; ++ struct iproc_usb_priv *iproc_usb_data; ++ int gpio_pin; ++ enum of_gpio_flags flags; ++ u32 gpio_active_low; ++ u32 __maybe_unused val; ++ int ret, usb_mode; ++ ++ if (!of_device_is_available(dn)) ++ return -ENODEV; ++ ++ iproc_usb_data = devm_kzalloc(dev, sizeof(*iproc_usb_data), GFP_KERNEL); ++ if (!iproc_usb_data) { ++ dev_err(dev, "devm_kzalloc() failed\n" ); ++ return -ENOMEM; ++ } ++ memset(iproc_usb_data, 0, sizeof(*iproc_usb_data)); ++ platform_set_drvdata(pdev, iproc_usb_data); ++ ++ iproc_usb_data->dev = dev; ++ iproc_usb_data->dn = dn; ++ ++ iproc_usb_data->wrap_base = get_iproc_wrap_ctrl_base(); ++ if (!iproc_usb_data->wrap_base) { ++ dev_err(&pdev->dev, "can't iomap usb phy base address\n"); ++ ret = -ENOMEM; ++ goto err1; ++ } ++ ++ gpio_pin = of_get_named_gpio_flags(dn, "vbus-gpio", 0, &flags); ++ ++ if (gpio_pin < 0) { ++ dev_err(&pdev->dev, "Error: no gpio pin set for USB power\n"); ++ return gpio_pin; ++ } ++ ++ gpio_active_low = flags & OF_GPIO_ACTIVE_LOW; ++ ++ ret = gpio_request(gpio_pin, "usbphy-vbus"); ++ if (ret != 0) { ++ dev_err(dev, "request gpio #%d error.\n", gpio_pin); ++ goto err1; ++ } ++ ++ usb_mode = xgs_iproc_usb_phy_mode(iproc_usb_data); ++ ++ iproc_usb_data->usb_mode = usb_mode; ++ iproc_usb_data->phy.dev = dev; ++ iproc_usb_data->phy.flags = usb_mode; ++ iproc_usb_data->phy.init = iproc_usb_phy_init; ++ iproc_usb_data->phy.type = USB_PHY_TYPE_USB2; ++ ++ if (usb_mode == IPROC_USB_MODE_DEVICE) { ++ iproc_usb_data->idm_base = (void *)of_iomap(dn, 1); ++ if (!iproc_usb_data->idm_base) { ++ dev_err(&pdev->dev, "can't iomap usb2d idm base address 1\n"); ++ ret = -ENOMEM; ++ goto err2; ++ } ++ ++ gpio_direction_input(gpio_pin); ++ } else { ++ ++#if defined(CONFIG_MACH_GH2) ++ USBH_Utmi_base = (void *)of_iomap(dn, 2); ++ if (!USBH_Utmi_base) { ++ dev_err(&pdev->dev, "can't iomap usb2h idm base address 2\n"); ++ ret = -ENOMEM; ++ goto err2; ++ } ++#endif ++ iproc_usb_data->idm_base = (void *)of_iomap(dn, 0); ++ if (!iproc_usb_data->idm_base) { ++ dev_err(&pdev->dev, "can't iomap usb2h idm base address 0\n"); ++ ret = -ENOMEM; ++ goto err2; ++ } ++ ++ gpio_direction_output(gpio_pin, 1); ++ ++ /*turn off the power: if active low for power, then set 1 to turn off*/ ++ if (gpio_active_low) ++ __gpio_set_value(gpio_pin, 1); ++ else ++ __gpio_set_value(gpio_pin, 0); ++ ++ /* ++ Initial usb phy for usb host mode. For the device mode, ++ the iproc_usb_phy_init will be called when usb udc start. ++ */ ++ ret = iproc_usb_phy_init(&iproc_usb_data->phy); ++ if (ret < 0) ++ goto err2; ++ } ++ ++ ret = usb_add_phy_dev(&iproc_usb_data->phy); ++ if (ret) ++ goto err2; ++ ++ /* supply power for USB device connected to the host */ ++ if (usb_mode != IPROC_USB_MODE_DEVICE) { ++ if (gpio_active_low) ++ __gpio_set_value(gpio_pin, 0); ++ else ++ __gpio_set_value(gpio_pin, 1); ++ } ++ gpio_free(gpio_pin); ++ ++ return 0; ++ ++err2: ++ gpio_free(gpio_pin); ++err1: ++ if (iproc_usb_data->idm_base) { ++ iounmap(iproc_usb_data->idm_base); ++ } ++ if (iproc_usb_data) { ++ iounmap(iproc_usb_data); ++ } ++#if defined(CONFIG_MACH_GH2) ++ if (USBH_Utmi_base) { ++ iounmap(USBH_Utmi_base); ++ USBH_Utmi_base = NULL; ++ } ++#endif ++ return ret; ++} ++ ++static int xgs_iproc_usb_phy_remove(struct platform_device *pdev) ++{ ++ struct iproc_usb_priv *iproc_usb_data = platform_get_drvdata(pdev); ++ ++ platform_set_drvdata(pdev, NULL); ++ if (iproc_usb_data->idm_base) { ++ iounmap(iproc_usb_data->idm_base); ++ usb_remove_phy(&iproc_usb_data->phy); ++ } ++ ++ if (iproc_usb_data) ++ iounmap(iproc_usb_data); ++ ++#if defined(CONFIG_MACH_GH2) ++ if (USBH_Utmi_base) { ++ iounmap(USBH_Utmi_base); ++ USBH_Utmi_base = NULL; ++ } ++#endif ++ ++ return 0; ++} ++ ++static struct platform_driver xgs_iproc_usb_phy_driver = ++{ ++ .driver = { ++ .name = "usb-phy", ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(xgs_iproc_usb_phy_dt_ids), ++ }, ++ .probe = xgs_iproc_usb_phy_probe, ++ .remove = xgs_iproc_usb_phy_remove, ++}; ++ ++module_platform_driver(xgs_iproc_usb_phy_driver); ++ ++MODULE_AUTHOR("Broadcom"); ++MODULE_DESCRIPTION("Broadcom USB phy driver"); ++MODULE_LICENSE("GPL"); +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig +--- a/drivers/watchdog/Kconfig 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/watchdog/Kconfig 2017-11-09 17:54:04.039439000 +0800 +@@ -578,6 +578,14 @@ config LPC18XX_WATCHDOG + To compile this driver as a module, choose M here: the + module will be called lpc18xx_wdt. + ++config XGS_IPROC_SP805_WDT ++ tristate "BRCM XGS iProc watchdog based on SP805" ++ depends on (ARCH_XGS_IPROC || COMPILE_TEST) ++ select WATCHDOG_CORE ++ help ++ Say Y here to include support for the watchdog timer ++ embedded in BRCM XGS iProc SoCs. ++ + # AVR32 Architecture + + config AT32AP700X_WDT +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile +--- a/drivers/watchdog/Makefile 2016-12-16 00:49:34.000000000 +0800 ++++ b/drivers/watchdog/Makefile 2017-11-09 17:54:04.040435000 +0800 +@@ -69,6 +69,7 @@ obj-$(CONFIG_MEDIATEK_WATCHDOG) += mtk_w + obj-$(CONFIG_DIGICOLOR_WATCHDOG) += digicolor_wdt.o + obj-$(CONFIG_LPC18XX_WATCHDOG) += lpc18xx_wdt.o + obj-$(CONFIG_BCM7038_WDT) += bcm7038_wdt.o ++obj-$(CONFIG_XGS_IPROC_SP805_WDT) += xgs_iproc_sp805_wdt.o + + # AVR32 Architecture + obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/watchdog/xgs_iproc_sp805_wdt.c b/drivers/watchdog/xgs_iproc_sp805_wdt.c +--- a/drivers/watchdog/xgs_iproc_sp805_wdt.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/watchdog/xgs_iproc_sp805_wdt.c 2017-11-09 17:54:04.252451000 +0800 +@@ -0,0 +1,381 @@ ++/* ++ * Copyright (C) 2015, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* default timeout in seconds */ ++#define DEFAULT_TIMEOUT 60 ++ ++#define MODULE_NAME "iproc-sp805-wdt" ++ ++/* watchdog register offsets and masks */ ++#define WDTLOAD 0x000 ++ #define LOAD_MIN 0x00000001 ++ #define LOAD_MAX 0xFFFFFFFF ++#define WDTVALUE 0x004 ++#define WDTCONTROL 0x008 ++ /* control register masks */ ++ #define INT_ENABLE (1 << 0) ++ #define RESET_ENABLE (1 << 1) ++#define WDTINTCLR 0x00C ++#define WDTRIS 0x010 ++#define WDTMIS 0x014 ++ #define INT_MASK (1 << 0) ++#define WDTLOCK 0xC00 ++ #define UNLOCK 0x1ACCE551 ++ #define LOCK 0x00000001 ++ ++/** ++ * struct sp805_wdt: sp805 wdt device structure ++ * @wdd: instance of struct watchdog_device ++ * @lock: spin lock protecting dev structure and io access ++ * @base: base address of wdt ++ * @clk: clock structure of wdt ++ * @adev: amba device structure of wdt ++ * @load_val: load value to be set for current timeout ++ */ ++struct sp805_wdt { ++ struct watchdog_device wdd; ++ spinlock_t lock; ++ void __iomem *base; ++ struct clk *clk; ++ struct amba_device *adev; ++ unsigned int load_val; ++}; ++ ++static bool nowayout = WATCHDOG_NOWAYOUT; ++module_param(nowayout, bool, 0); ++MODULE_PARM_DESC(nowayout, ++ "Set to 1 to keep watchdog running after device release"); ++ ++/* This routine get boot status to indicate if the last boot is from WDT */ ++static unsigned int wdt_get_clear_bootstatus( ++ void __iomem *wdt_bootstatus, ++ unsigned int wdt_bootstatus_bit) ++{ ++ unsigned int reg; ++ unsigned int bootstatus = 0; ++ ++ reg = readl_relaxed(wdt_bootstatus); ++ bootstatus = reg & (1 << wdt_bootstatus_bit); ++ ++ if (bootstatus) ++ /* write 1 to clear boot status bit */ ++ writel_relaxed(reg, wdt_bootstatus); ++ ++ return bootstatus; ++} ++ ++/* This routine finds load value that will reset system in required timout */ ++static int wdt_setload(struct watchdog_device *wdd, unsigned int timeout) ++{ ++ struct sp805_wdt *wdt = watchdog_get_drvdata(wdd); ++ u64 load, rate; ++ ++ rate = clk_get_rate(wdt->clk); ++ ++ /* ++ * sp805 runs counter with given value twice, after the end of first ++ * counter it gives an interrupt and then starts counter again. If ++ * interrupt already occurred then it resets the system. This is why ++ * load is half of what should be required. ++ */ ++ load = div_u64(rate, 2) * timeout - 1; ++ ++ load = (load > LOAD_MAX) ? LOAD_MAX : load; ++ load = (load < LOAD_MIN) ? LOAD_MIN : load; ++ ++ spin_lock(&wdt->lock); ++ wdt->load_val = load; ++ /* roundup timeout to closest positive integer value */ ++ wdd->timeout = div_u64((load + 1) * 2 + (rate / 2), rate); ++ spin_unlock(&wdt->lock); ++ ++ return 0; ++} ++ ++/* returns number of seconds left for reset to occur */ ++static unsigned int wdt_timeleft(struct watchdog_device *wdd) ++{ ++ struct sp805_wdt *wdt = watchdog_get_drvdata(wdd); ++ u64 load, rate; ++ ++ rate = clk_get_rate(wdt->clk); ++ ++ spin_lock(&wdt->lock); ++ load = readl_relaxed(wdt->base + WDTVALUE); ++ ++ /* If the interrupt is inactive then time left is WDTValue + WDTLoad. */ ++ if (!(readl_relaxed(wdt->base + WDTRIS) & INT_MASK)) ++ load += wdt->load_val + 1; ++ spin_unlock(&wdt->lock); ++ ++ return div_u64(load, rate); ++} ++ ++static int wdt_config(struct watchdog_device *wdd, bool ping) ++{ ++ struct sp805_wdt *wdt = watchdog_get_drvdata(wdd); ++ int ret; ++ ++ if (!ping) { ++ ret = clk_prepare(wdt->clk); ++ if (ret) { ++ dev_err(&wdt->adev->dev, "clock prepare fail"); ++ return ret; ++ } ++ ++ ret = clk_enable(wdt->clk); ++ if (ret) { ++ dev_err(&wdt->adev->dev, "clock enable fail"); ++ clk_unprepare(wdt->clk); ++ return ret; ++ } ++ } ++ ++ spin_lock(&wdt->lock); ++ ++ writel_relaxed(UNLOCK, wdt->base + WDTLOCK); ++ writel_relaxed(wdt->load_val, wdt->base + WDTLOAD); ++ writel_relaxed(INT_MASK, wdt->base + WDTINTCLR); ++ ++ if (!ping) ++ writel_relaxed(INT_ENABLE | RESET_ENABLE, wdt->base + ++ WDTCONTROL); ++ ++ writel_relaxed(LOCK, wdt->base + WDTLOCK); ++ ++ /* Flush posted writes. */ ++ readl_relaxed(wdt->base + WDTLOCK); ++ spin_unlock(&wdt->lock); ++ ++ return 0; ++} ++ ++static int wdt_ping(struct watchdog_device *wdd) ++{ ++ return wdt_config(wdd, true); ++} ++ ++/* enables watchdog timers reset */ ++static int wdt_enable(struct watchdog_device *wdd) ++{ ++ return wdt_config(wdd, false); ++} ++ ++/* disables watchdog timers reset */ ++static int wdt_disable(struct watchdog_device *wdd) ++{ ++ struct sp805_wdt *wdt = watchdog_get_drvdata(wdd); ++ ++ spin_lock(&wdt->lock); ++ ++ writel_relaxed(UNLOCK, wdt->base + WDTLOCK); ++ writel_relaxed(0, wdt->base + WDTCONTROL); ++ writel_relaxed(LOCK, wdt->base + WDTLOCK); ++ ++ /* Flush posted writes. */ ++ readl_relaxed(wdt->base + WDTLOCK); ++ spin_unlock(&wdt->lock); ++ ++ clk_disable(wdt->clk); ++ clk_unprepare(wdt->clk); ++ ++ return 0; ++} ++ ++static const struct watchdog_info wdt_info = { ++ .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, ++ .identity = MODULE_NAME, ++}; ++ ++static const struct watchdog_ops wdt_ops = { ++ .owner = THIS_MODULE, ++ .start = wdt_enable, ++ .stop = wdt_disable, ++ .ping = wdt_ping, ++ .set_timeout = wdt_setload, ++ .get_timeleft = wdt_timeleft, ++}; ++ ++static int sp805_wdt_probe(struct amba_device *adev, const struct amba_id *id) ++{ ++ struct sp805_wdt *wdt; ++ int ret; ++ struct device_node *dnode = adev->dev.of_node; ++ void __iomem *wdt_bootstatus = NULL; ++ unsigned int bootstatus_bit = 0; ++ ++ wdt = devm_kzalloc(&adev->dev, sizeof(*wdt), GFP_KERNEL); ++ if (!wdt) { ++ dev_err(&adev->dev, "Kzalloc failed\n"); ++ ret = -ENOMEM; ++ goto error1; ++ } ++ ++ wdt->base = of_iomap(dnode, 0); ++ if (!wdt->base) { ++ ret = -ENOMEM; ++ dev_err(&adev->dev, "of_iomap failed\n"); ++ goto error2; ++ } ++ ++ wdt_bootstatus = of_iomap(dnode, 1); ++ if (!wdt_bootstatus) { ++ ret = -ENOMEM; ++ dev_err(&adev->dev, "of_iomap failed\n"); ++ goto error2; ++ } ++ ++ wdt->clk = of_clk_get(dnode, 0); ++ if (IS_ERR(wdt->clk)) { ++ dev_err(&adev->dev, "Clock not found\n"); ++ ret = PTR_ERR(wdt->clk); ++ goto error2; ++ } ++ ++ wdt->adev = adev; ++ wdt->wdd.info = &wdt_info; ++ wdt->wdd.ops = &wdt_ops; ++ ++ spin_lock_init(&wdt->lock); ++ watchdog_set_nowayout(&wdt->wdd, nowayout); ++ watchdog_set_drvdata(&wdt->wdd, wdt); ++ wdt_setload(&wdt->wdd, DEFAULT_TIMEOUT); ++ ++ ret = watchdog_register_device(&wdt->wdd); ++ if (ret) { ++ dev_err(&adev->dev, "watchdog_register_device() failed: %d\n", ++ ret); ++ goto error3; ++ } ++ ++ amba_set_drvdata(adev, wdt); ++ ++ ret = of_property_read_u32(dnode, "wdt_boot_status_bit", ++ &bootstatus_bit); ++ if (ret) { ++ dev_err(&adev->dev, "failed getting DT bootstatus bit\n"); ++ goto error3; ++ } ++ ++ wdt->wdd.bootstatus = wdt_get_clear_bootstatus( ++ wdt_bootstatus, ++ bootstatus_bit); ++ ++ dev_info(&adev->dev, "registration successful\n"); ++ dev_info(&adev->dev, "timeout=%d sec, nowayout=%d\n", ++ DEFAULT_TIMEOUT, nowayout); ++ ++ return 0; ++ ++error3: ++ clk_put(wdt->clk); ++ ++error2: ++ if (wdt->base) ++ iounmap(wdt->base); ++ if (wdt_bootstatus) ++ iounmap(wdt_bootstatus); ++ kfree(wdt); ++ ++error1: ++ dev_err(&adev->dev, "Probe Failed!!!\n"); ++ ++ return ret; ++} ++ ++static int sp805_wdt_remove(struct amba_device *adev) ++{ ++ struct sp805_wdt *wdt = amba_get_drvdata(adev); ++ ++ watchdog_unregister_device(&wdt->wdd); ++ amba_set_drvdata(adev, NULL); ++ watchdog_set_drvdata(&wdt->wdd, NULL); ++ clk_put(wdt->clk); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++static int sp805_wdt_suspend(struct device *dev) ++{ ++ struct sp805_wdt *wdt = dev_get_drvdata(dev); ++ ++ if (watchdog_active(&wdt->wdd)) ++ return wdt_disable(&wdt->wdd); ++ ++ return 0; ++} ++ ++static int sp805_wdt_resume(struct device *dev) ++{ ++ struct sp805_wdt *wdt = dev_get_drvdata(dev); ++ ++ if (watchdog_active(&wdt->wdd)) ++ return wdt_enable(&wdt->wdd); ++ ++ return 0; ++} ++#endif /* CONFIG_PM */ ++ ++static SIMPLE_DEV_PM_OPS(sp805_wdt_dev_pm_ops, sp805_wdt_suspend, ++ sp805_wdt_resume); ++ ++static struct amba_id sp805_wdt_ids[] = { ++ { ++ .id = 0x00141805, ++ .mask = 0x00ffffff, ++ }, ++ { 0, 0 }, ++}; ++MODULE_DEVICE_TABLE(amba, sp805_wdt_ids); ++ ++static struct amba_driver sp805_wdt_driver = { ++ .drv = { ++ .name = MODULE_NAME, ++ .pm = &sp805_wdt_dev_pm_ops, ++ }, ++ .id_table = sp805_wdt_ids, ++ .probe = sp805_wdt_probe, ++ .remove = sp805_wdt_remove, ++}; ++ ++module_amba_driver(sp805_wdt_driver); ++ ++MODULE_AUTHOR("Viresh Kumar "); ++MODULE_DESCRIPTION("ARM SP805 Watchdog Driver"); ++MODULE_LICENSE("GPL"); +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h +--- a/include/linux/mtd/spi-nor.h 2016-12-16 00:49:34.000000000 +0800 ++++ b/include/linux/mtd/spi-nor.h 2017-11-09 17:54:11.415490000 +0800 +@@ -183,6 +183,9 @@ struct spi_nor { + int (*flash_is_locked)(struct spi_nor *nor, loff_t ofs, uint64_t len); + + void *priv; ++#ifdef CONFIG_M25PXX_STAY_IN_3BYTE_MODE ++ void *priv1; ++#endif + }; + + /** +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/include/linux/soc/bcm/xgs-iproc-wrap-idm-dmu.h b/include/linux/soc/bcm/xgs-iproc-wrap-idm-dmu.h +--- a/include/linux/soc/bcm/xgs-iproc-wrap-idm-dmu.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/include/linux/soc/bcm/xgs-iproc-wrap-idm-dmu.h 2017-11-09 17:54:12.456502000 +0800 +@@ -0,0 +1,15 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ */ ++ ++#ifndef XGS_IPROC_WRAP_IDM_DMU_H ++#define XGS_IPROC_WRAP_IDM_DMU_H ++ ++extern int xgs_iproc_wrap_idm_dmu_base_reg_setup(void); ++extern void xgs_iproc_idm_timeout_handler_setup(void); ++extern void __iomem *get_iproc_wrap_ctrl_base(void); ++extern void __iomem *get_iproc_dmu_pcu_base(void); ++extern void __iomem *get_iproc_idm_base(int index); ++extern void __iomem *get_iproc_idm_base_phys(int index); ++ ++#endif +diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/include/linux/usb/iproc_usb.h b/include/linux/usb/iproc_usb.h +--- a/include/linux/usb/iproc_usb.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/include/linux/usb/iproc_usb.h 2017-11-09 17:54:12.826524000 +0800 +@@ -0,0 +1,20 @@ ++/* ++ * iproc_usb.h -- USB defines for XGS IPROC USB drivers ++ * ++ * Copyright (C) 2015 Broadcom Limited. ++ * ++ * This software is distributed under the terms of the GNU General ++ * Public License ("GPL") as published by the Free Software Foundation, ++ * version 2 of that License. ++ */ ++ ++#ifndef __LINUX_USB_IPROC_USB_H ++#define __LINUX_USB_IPROC_USB_H ++ ++/* USB Flags */ ++ ++#define IPROC_USB_MODE_HOST (0) ++#define IPROC_USB_MODE_DEVICE (1) ++ ++#endif /* __LINUX_USB_IPROC_USB_H */ ++ diff --git a/packages/base/any/kernels/4.4-lts/patches/series b/packages/base/any/kernels/4.4-lts/patches/series new file mode 100644 index 00000000..db86ea76 --- /dev/null +++ b/packages/base/any/kernels/4.4-lts/patches/series @@ -0,0 +1 @@ +kernel-4.4-brcm-iproc.patch