1
0
Fork 0
mirror of https://github.com/Ysurac/openmptcprouter.git synced 2025-03-09 15:40:20 +00:00

Merge branch 'test' into develop

This commit is contained in:
suyuan 2021-12-07 02:53:16 +08:00
commit d16eb48e92
247 changed files with 115529 additions and 0 deletions

View file

@ -538,6 +538,7 @@ if [ "$OMR_KERNEL" = "5.14" ]; then
echo "Set to kernel 5.14 for rpi arch" echo "Set to kernel 5.14 for rpi arch"
find target/linux/bcm27xx -type f -name Makefile -exec sed -i 's%KERNEL_PATCHVER:=5.10%KERNEL_PATCHVER:=5.14%g' {} \; find target/linux/bcm27xx -type f -name Makefile -exec sed -i 's%KERNEL_PATCHVER:=5.10%KERNEL_PATCHVER:=5.14%g' {} \;
find target/linux/bcm27xx -type f -name Makefile -exec sed -i 's%KERNEL_PATCHVER=5.10%KERNEL_PATCHVER:=5.14%g' {} \; find target/linux/bcm27xx -type f -name Makefile -exec sed -i 's%KERNEL_PATCHVER=5.10%KERNEL_PATCHVER:=5.14%g' {} \;
find target/linux/bcm27xx -type f -name Makefile -exec sed -i 's%KERNEL_PATCHVER=5.4%KERNEL_PATCHVER:=5.14%g' {} \;
echo "Done" echo "Done"
echo "Set to kernel 5.14 for x86 arch" echo "Set to kernel 5.14 for x86 arch"
find target/linux/x86 -type f -name Makefile -exec sed -i 's%KERNEL_PATCHVER:=5.10%KERNEL_PATCHVER:=5.14%g' {} \; find target/linux/x86 -type f -name Makefile -exec sed -i 's%KERNEL_PATCHVER:=5.10%KERNEL_PATCHVER:=5.14%g' {} \;
@ -576,6 +577,7 @@ if [ "$OMR_KERNEL" = "5.15" ]; then
echo "Set to kernel 5.15 for rpi arch" echo "Set to kernel 5.15 for rpi arch"
find target/linux/bcm27xx -type f -name Makefile -exec sed -i 's%KERNEL_PATCHVER:=5.10%KERNEL_PATCHVER:=5.15%g' {} \; find target/linux/bcm27xx -type f -name Makefile -exec sed -i 's%KERNEL_PATCHVER:=5.10%KERNEL_PATCHVER:=5.15%g' {} \;
find target/linux/bcm27xx -type f -name Makefile -exec sed -i 's%KERNEL_PATCHVER=5.10%KERNEL_PATCHVER:=5.15%g' {} \; find target/linux/bcm27xx -type f -name Makefile -exec sed -i 's%KERNEL_PATCHVER=5.10%KERNEL_PATCHVER:=5.15%g' {} \;
find target/linux/bcm27xx -type f -name Makefile -exec sed -i 's%KERNEL_PATCHVER=5.4%KERNEL_PATCHVER:=5.15%g' {} \;
echo "Done" echo "Done"
echo "Set to kernel 5.15 for x86 arch" echo "Set to kernel 5.15 for x86 arch"
find target/linux/x86 -type f -name Makefile -exec sed -i 's%KERNEL_PATCHVER:=5.10%KERNEL_PATCHVER:=5.15%g' {} \; find target/linux/x86 -type f -name Makefile -exec sed -i 's%KERNEL_PATCHVER:=5.10%KERNEL_PATCHVER:=5.15%g' {} \;

View file

@ -0,0 +1,505 @@
CONFIG_ALIGNMENT_TRAP=y
# CONFIG_APQ_GCC_8084 is not set
# CONFIG_APQ_MMCC_8084 is not set
CONFIG_AR8216_PHY=y
CONFIG_ARCH_32BIT_OFF_T=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
# CONFIG_ARCH_IPQ40XX is not set
CONFIG_ARCH_KEEP_MEMBLOCK=y
# CONFIG_ARCH_MDM9615 is not set
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
CONFIG_ARCH_MSM8960=y
CONFIG_ARCH_MSM8974=y
CONFIG_ARCH_MSM8X60=y
CONFIG_ARCH_MULTIPLATFORM=y
CONFIG_ARCH_MULTI_V6_V7=y
CONFIG_ARCH_MULTI_V7=y
CONFIG_ARCH_NR_GPIO=0
CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
CONFIG_ARCH_QCOM=y
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ARM=y
CONFIG_ARM_AMBA=y
CONFIG_ARM_APPENDED_DTB=y
CONFIG_ARM_ARCH_TIMER=y
CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
CONFIG_ARM_ATAG_DTB_COMPAT=y
# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER is not set
CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE=y
CONFIG_ARM_CPUIDLE=y
CONFIG_ARM_CPU_SUSPEND=y
# CONFIG_ARM_CPU_TOPOLOGY is not set
CONFIG_ARM_GIC=y
CONFIG_ARM_HAS_SG_CHAIN=y
CONFIG_ARM_L1_CACHE_SHIFT=6
CONFIG_ARM_L1_CACHE_SHIFT_6=y
CONFIG_ARM_MODULE_PLTS=y
CONFIG_ARM_PATCH_IDIV=y
CONFIG_ARM_PATCH_PHYS_VIRT=y
# CONFIG_ARM_QCOM_CPUFREQ_HW is not set
CONFIG_ARM_QCOM_CPUFREQ_KRAIT=y
CONFIG_ARM_QCOM_CPUFREQ_NVMEM=y
CONFIG_ARM_QCOM_SPM_CPUIDLE=y
# CONFIG_ARM_SMMU is not set
CONFIG_ARM_THUMB=y
CONFIG_ARM_UNWIND=y
CONFIG_ARM_VIRT_EXT=y
CONFIG_AT803X_PHY=y
CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_MQ_PCI=y
CONFIG_BOUNCE=y
# CONFIG_CACHE_L2X0 is not set
CONFIG_CLKDEV_LOOKUP=y
CONFIG_CLKSRC_QCOM=y
CONFIG_CLONE_BACKWARDS=y
CONFIG_CMDLINE_OVERRIDE=y
CONFIG_COMMON_CLK=y
CONFIG_COMMON_CLK_QCOM=y
CONFIG_COMPAT_32BIT_TIME=y
CONFIG_CPUFREQ_DT=y
CONFIG_CPUFREQ_DT_PLATDEV=y
CONFIG_CPU_32v6K=y
CONFIG_CPU_32v7=y
CONFIG_CPU_ABRT_EV7=y
CONFIG_CPU_CACHE_V7=y
CONFIG_CPU_CACHE_VIPT=y
CONFIG_CPU_COPY_V6=y
CONFIG_CPU_CP15=y
CONFIG_CPU_CP15_MMU=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
CONFIG_CPU_FREQ_GOV_ATTR_SET=y
CONFIG_CPU_FREQ_GOV_COMMON=y
# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
CONFIG_CPU_FREQ_STAT=y
CONFIG_CPU_HAS_ASID=y
CONFIG_CPU_IDLE=y
CONFIG_CPU_IDLE_GOV_LADDER=y
CONFIG_CPU_IDLE_GOV_MENU=y
CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y
CONFIG_CPU_PABRT_V7=y
CONFIG_CPU_PM=y
CONFIG_CPU_RMAP=y
CONFIG_CPU_SPECTRE=y
CONFIG_CPU_THERMAL=y
CONFIG_CPU_THUMB_CAPABLE=y
CONFIG_CPU_TLB_V7=y
CONFIG_CPU_V7=y
CONFIG_CRC16=y
# CONFIG_CRC32_SARWATE is not set
CONFIG_CRC32_SLICEBY8=y
CONFIG_CRYPTO_ACOMP2=y
CONFIG_CRYPTO_AEAD=y
CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_DEFLATE=y
CONFIG_CRYPTO_DEV_QCOM_RNG=y
CONFIG_CRYPTO_DRBG=y
CONFIG_CRYPTO_DRBG_HMAC=y
CONFIG_CRYPTO_DRBG_MENU=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_HASH_INFO=y
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_HW=y
CONFIG_CRYPTO_JITTERENTROPY=y
CONFIG_CRYPTO_LIB_SHA256=y
CONFIG_CRYPTO_LZO=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
CONFIG_CRYPTO_NULL2=y
CONFIG_CRYPTO_RNG=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_ZSTD=y
CONFIG_DCACHE_WORD_ACCESS=y
CONFIG_DEBUG_GPIO=y
CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
# CONFIG_DEVFREQ_GOV_PASSIVE is not set
# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set
# CONFIG_DEVFREQ_GOV_POWERSAVE is not set
# CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND is not set
# CONFIG_DEVFREQ_GOV_USERSPACE is not set
# CONFIG_DEVFREQ_THERMAL is not set
CONFIG_DMADEVICES=y
CONFIG_DMA_ENGINE=y
CONFIG_DMA_OF=y
CONFIG_DMA_OPS=y
CONFIG_DMA_REMAP=y
CONFIG_DMA_VIRTUAL_CHANNELS=y
CONFIG_DTC=y
CONFIG_DT_IDLE_STATES=y
# CONFIG_DWMAC_GENERIC is not set
CONFIG_DWMAC_IPQ806X=y
# CONFIG_DWMAC_QCOM_ETHQOS is not set
CONFIG_DYNAMIC_DEBUG=y
CONFIG_EDAC_ATOMIC_SCRUB=y
CONFIG_EDAC_SUPPORT=y
CONFIG_FIXED_PHY=y
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_GENERIC_CPU_AUTOPROBE=y
CONFIG_GENERIC_EARLY_IOREMAP=y
CONFIG_GENERIC_GETTIMEOFDAY=y
CONFIG_GENERIC_IDLE_POLL_SETUP=y
CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
CONFIG_GENERIC_MSI_IRQ=y
CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_PHY=y
CONFIG_GENERIC_PINCONF=y
CONFIG_GENERIC_PINCTRL_GROUPS=y
CONFIG_GENERIC_PINMUX_FUNCTIONS=y
CONFIG_GENERIC_SCHED_CLOCK=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GENERIC_VDSO_32=y
CONFIG_GPIOLIB=y
CONFIG_GPIOLIB_IRQCHIP=y
CONFIG_GRO_CELLS=y
CONFIG_HANDLE_DOMAIN_IRQ=y
CONFIG_HARDEN_BRANCH_PREDICTOR=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT_MAP=y
CONFIG_HAVE_SMP=y
CONFIG_HIGHMEM=y
# CONFIG_HIGHPTE is not set
CONFIG_HWMON=y
CONFIG_HWSPINLOCK=y
CONFIG_HWSPINLOCK_QCOM=y
CONFIG_HW_RANDOM=y
CONFIG_HZ=100
CONFIG_HZ_100=y
CONFIG_HZ_FIXED=0
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
# CONFIG_I2C_QCOM_CCI is not set
CONFIG_I2C_QUP=y
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_IOMMU_DEBUGFS is not set
# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set
# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set
CONFIG_IOMMU_SUPPORT=y
# CONFIG_IPQ_APSS_PLL is not set
# CONFIG_IPQ_GCC_4019 is not set
# CONFIG_IPQ_GCC_6018 is not set
CONFIG_IPQ_GCC_806X=y
# CONFIG_IPQ_GCC_8074 is not set
# CONFIG_IPQ_LCC_806X is not set
CONFIG_IRQCHIP=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_DOMAIN_HIERARCHY=y
CONFIG_IRQ_FASTEOI_HIERARCHY_HANDLERS=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_IRQ_WORK=y
CONFIG_KPSS_XCC=y
CONFIG_KRAITCC=y
CONFIG_KRAIT_CLOCKS=y
CONFIG_KRAIT_L2_ACCESSORS=y
CONFIG_LIBFDT=y
CONFIG_LLD_VERSION=0
CONFIG_LOCK_DEBUGGING_SUPPORT=y
CONFIG_LOCK_SPIN_ON_OWNER=y
CONFIG_LZO_COMPRESS=y
CONFIG_LZO_DECOMPRESS=y
CONFIG_MDIO_BITBANG=y
CONFIG_MDIO_BUS=y
CONFIG_MDIO_DEVICE=y
CONFIG_MDIO_GPIO=y
CONFIG_MDIO_IPQ8064=y
# CONFIG_MDM_GCC_9615 is not set
# CONFIG_MDM_LCC_9615 is not set
CONFIG_MEMFD_CREATE=y
# CONFIG_MFD_HI6421_SPMI is not set
CONFIG_MFD_QCOM_RPM=y
# CONFIG_MFD_SPMI_PMIC is not set
CONFIG_MFD_SYSCON=y
CONFIG_MIGHT_HAVE_CACHE_L2X0=y
CONFIG_MIGRATION=y
CONFIG_MMC=y
CONFIG_MMC_ARMMMCI=y
CONFIG_MMC_BLOCK=y
CONFIG_MMC_BLOCK_MINORS=16
CONFIG_MMC_CQHCI=y
CONFIG_MMC_QCOM_DML=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_IO_ACCESSORS=y
CONFIG_MMC_SDHCI_MSM=y
# CONFIG_MMC_SDHCI_PCI is not set
CONFIG_MMC_SDHCI_PLTFM=y
# CONFIG_MMC_TIFM_SD is not set
CONFIG_MODULES_USE_ELF_REL=y
CONFIG_MSM_GCC_8660=y
# CONFIG_MSM_GCC_8916 is not set
# CONFIG_MSM_GCC_8939 is not set
# CONFIG_MSM_GCC_8960 is not set
# CONFIG_MSM_GCC_8974 is not set
# CONFIG_MSM_GCC_8994 is not set
# CONFIG_MSM_GCC_8996 is not set
# CONFIG_MSM_GCC_8998 is not set
# CONFIG_MSM_GPUCC_8998 is not set
# CONFIG_MSM_IOMMU is not set
# CONFIG_MSM_LCC_8960 is not set
# CONFIG_MSM_MMCC_8960 is not set
# CONFIG_MSM_MMCC_8974 is not set
# CONFIG_MSM_MMCC_8996 is not set
# CONFIG_MSM_MMCC_8998 is not set
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_NAND_CORE=y
CONFIG_MTD_NAND_ECC=y
CONFIG_MTD_NAND_ECC_SW_HAMMING=y
CONFIG_MTD_NAND_QCOM=y
CONFIG_MTD_QCOMSMEM_PARTS=y
CONFIG_MTD_RAW_NAND=y
CONFIG_MTD_SPI_NOR=y
CONFIG_MTD_SPLIT_FIRMWARE=y
CONFIG_MTD_SPLIT_FIT_FW=y
CONFIG_MTD_SPLIT_UIMAGE_FW=y
CONFIG_MTD_UBI=y
CONFIG_MTD_UBI_BEB_LIMIT=20
CONFIG_MTD_UBI_BLOCK=y
CONFIG_MTD_UBI_WL_THRESHOLD=4096
CONFIG_MUTEX_SPIN_ON_OWNER=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_NEON=y
CONFIG_NET_DEVLINK=y
CONFIG_NET_DSA=y
CONFIG_NET_DSA_QCA8K=y
CONFIG_NET_DSA_TAG_QCA=y
CONFIG_NET_FLOW_LIMIT=y
CONFIG_NET_PTP_CLASSIFY=y
CONFIG_NET_SWITCHDEV=y
CONFIG_NLS=y
CONFIG_NO_HZ=y
CONFIG_NO_HZ_COMMON=y
CONFIG_NO_HZ_IDLE=y
CONFIG_NR_CPUS=2
CONFIG_NVMEM=y
# CONFIG_NVMEM_SPMI_SDAM is not set
CONFIG_OF=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_EARLY_FLATTREE=y
CONFIG_OF_FLATTREE=y
CONFIG_OF_GPIO=y
CONFIG_OF_IRQ=y
CONFIG_OF_KOBJ=y
CONFIG_OF_MDIO=y
CONFIG_OF_NET=y
CONFIG_OLD_SIGACTION=y
CONFIG_OLD_SIGSUSPEND3=y
CONFIG_PADATA=y
CONFIG_PAGE_OFFSET=0xC0000000
CONFIG_PAGE_POOL=y
CONFIG_PCI=y
CONFIG_PCIEAER=y
CONFIG_PCIEPORTBUS=y
CONFIG_PCIE_DW=y
CONFIG_PCIE_DW_HOST=y
CONFIG_PCIE_QCOM=y
CONFIG_PCI_DEBUG=y
CONFIG_PCI_DISABLE_COMMON_QUIRKS=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCI_DOMAINS_GENERIC=y
CONFIG_PCI_MSI=y
CONFIG_PCI_MSI_IRQ_DOMAIN=y
CONFIG_PCS_XPCS=y
CONFIG_PERF_USE_VMALLOC=y
CONFIG_PGTABLE_LEVELS=2
CONFIG_PHYLIB=y
CONFIG_PHYLINK=y
# CONFIG_PHY_QCOM_APQ8064_SATA is not set
# CONFIG_PHY_QCOM_IPQ4019_USB is not set
CONFIG_PHY_QCOM_IPQ806X_SATA=y
# CONFIG_PHY_QCOM_IPQ806X_USB is not set
# CONFIG_PHY_QCOM_PCIE2 is not set
# CONFIG_PHY_QCOM_QMP is not set
# CONFIG_PHY_QCOM_QUSB2 is not set
# CONFIG_PHY_QCOM_USB_HS_28NM is not set
# CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2 is not set
# CONFIG_PHY_QCOM_USB_SS is not set
CONFIG_PINCTRL=y
# CONFIG_PINCTRL_APQ8064 is not set
# CONFIG_PINCTRL_APQ8084 is not set
# CONFIG_PINCTRL_IPQ4019 is not set
# CONFIG_PINCTRL_IPQ6018 is not set
CONFIG_PINCTRL_IPQ8064=y
# CONFIG_PINCTRL_IPQ8074 is not set
# CONFIG_PINCTRL_MDM9615 is not set
CONFIG_PINCTRL_MSM=y
# CONFIG_PINCTRL_MSM8226 is not set
# CONFIG_PINCTRL_MSM8660 is not set
# CONFIG_PINCTRL_MSM8916 is not set
# CONFIG_PINCTRL_MSM8960 is not set
# CONFIG_PINCTRL_MSM8976 is not set
# CONFIG_PINCTRL_MSM8994 is not set
# CONFIG_PINCTRL_MSM8996 is not set
# CONFIG_PINCTRL_MSM8998 is not set
# CONFIG_PINCTRL_QCOM_SPMI_PMIC is not set
# CONFIG_PINCTRL_QCOM_SSBI_PMIC is not set
# CONFIG_PINCTRL_QCS404 is not set
# CONFIG_PINCTRL_SC7180 is not set
# CONFIG_PINCTRL_SDM660 is not set
# CONFIG_PINCTRL_SDM845 is not set
# CONFIG_PINCTRL_SM8150 is not set
# CONFIG_PINCTRL_SM8250 is not set
CONFIG_PM_DEVFREQ=y
# CONFIG_PM_DEVFREQ_EVENT is not set
CONFIG_PM_OPP=y
CONFIG_POWER_RESET=y
CONFIG_POWER_RESET_MSM=y
CONFIG_POWER_SUPPLY=y
CONFIG_PPS=y
CONFIG_PRINTK_TIME=y
CONFIG_PTP_1588_CLOCK=y
# CONFIG_QCOM_A53PLL is not set
CONFIG_QCOM_ADM=y
CONFIG_QCOM_BAM_DMA=y
CONFIG_QCOM_CLK_RPM=y
# CONFIG_QCOM_COMMAND_DB is not set
# CONFIG_QCOM_CPR is not set
# CONFIG_QCOM_EBI2 is not set
# CONFIG_QCOM_GENI_SE is not set
CONFIG_QCOM_GSBI=y
CONFIG_QCOM_HFPLL=y
# CONFIG_QCOM_IOMMU is not set
# CONFIG_QCOM_LLCC is not set
# CONFIG_QCOM_OCMEM is not set
# CONFIG_QCOM_PDC is not set
CONFIG_QCOM_QFPROM=y
# CONFIG_QCOM_RMTFS_MEM is not set
CONFIG_QCOM_RPMCC=y
# CONFIG_QCOM_RPMH is not set
CONFIG_QCOM_SCM=y
# CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT is not set
CONFIG_QCOM_SMEM=y
# CONFIG_QCOM_SMSM is not set
# CONFIG_QCOM_SOCINFO is not set
CONFIG_QCOM_TCSR=y
CONFIG_QCOM_TSENS=y
CONFIG_QCOM_WDT=y
# CONFIG_QCS_GCC_404 is not set
# CONFIG_QCS_Q6SSTOP_404 is not set
# CONFIG_QCS_TURING_404 is not set
CONFIG_RAS=y
CONFIG_RATIONAL=y
CONFIG_REGMAP=y
CONFIG_REGMAP_MMIO=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
# CONFIG_REGULATOR_QCOM_LABIBB is not set
CONFIG_REGULATOR_QCOM_RPM=y
# CONFIG_REGULATOR_QCOM_SPMI is not set
# CONFIG_REGULATOR_QCOM_USB_VBUS is not set
# CONFIG_REGULATOR_VQMMC_IPQ4019 is not set
CONFIG_RESET_CONTROLLER=y
# CONFIG_RESET_QCOM_AOSS is not set
# CONFIG_RESET_QCOM_PDC is not set
CONFIG_RFS_ACCEL=y
CONFIG_RPS=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_I2C_AND_SPI=y
CONFIG_RTC_MC146818_LIB=y
CONFIG_RWSEM_SPIN_ON_OWNER=y
# CONFIG_SC_DISPCC_7180 is not set
# CONFIG_SC_GCC_7180 is not set
# CONFIG_SC_GPUCC_7180 is not set
# CONFIG_SC_LPASS_CORECC_7180 is not set
# CONFIG_SC_MSS_7180 is not set
# CONFIG_SC_VIDEOCC_7180 is not set
# CONFIG_SDM_CAMCC_845 is not set
# CONFIG_SDM_DISPCC_845 is not set
# CONFIG_SDM_GCC_660 is not set
# CONFIG_SDM_GCC_845 is not set
# CONFIG_SDM_GPUCC_845 is not set
# CONFIG_SDM_LPASSCC_845 is not set
# CONFIG_SDM_VIDEOCC_845 is not set
CONFIG_SERIAL_8250_FSL=y
CONFIG_SERIAL_MCTRL_GPIO=y
CONFIG_SERIAL_MSM=y
CONFIG_SERIAL_MSM_CONSOLE=y
CONFIG_SGL_ALLOC=y
CONFIG_SMP=y
CONFIG_SMP_ON_UP=y
# CONFIG_SM_GCC_8150 is not set
# CONFIG_SM_GCC_8250 is not set
# CONFIG_SM_GPUCC_8150 is not set
# CONFIG_SM_GPUCC_8250 is not set
# CONFIG_SM_VIDEOCC_8150 is not set
# CONFIG_SM_VIDEOCC_8250 is not set
CONFIG_SPARSE_IRQ=y
CONFIG_SPI=y
CONFIG_SPI_MASTER=y
CONFIG_SPI_MEM=y
CONFIG_SPI_QUP=y
CONFIG_SPMI=y
# CONFIG_SPMI_HISI3670 is not set
CONFIG_SPMI_MSM_PMIC_ARB=y
# CONFIG_SPMI_PMIC_CLKDIV is not set
CONFIG_SRCU=y
CONFIG_STMMAC_ETH=y
CONFIG_STMMAC_PLATFORM=y
# CONFIG_STMMAC_SELFTESTS is not set
CONFIG_SWCONFIG=y
CONFIG_SWCONFIG_LEDS=y
CONFIG_SWPHY=y
CONFIG_SWP_EMULATE=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
CONFIG_THERMAL=y
CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
CONFIG_THERMAL_GOV_STEP_WISE=y
CONFIG_THERMAL_HWMON=y
CONFIG_THERMAL_OF=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
CONFIG_UBIFS_FS=y
CONFIG_UBIFS_FS_ADVANCED_COMPR=y
CONFIG_UBIFS_FS_LZO=y
CONFIG_UBIFS_FS_ZLIB=y
CONFIG_UBIFS_FS_ZSTD=y
# CONFIG_UCLAMP_TASK is not set
CONFIG_UEVENT_HELPER_PATH=""
CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
CONFIG_UNWINDER_ARM=y
CONFIG_USB=y
CONFIG_USB_COMMON=y
CONFIG_USB_SUPPORT=y
CONFIG_USE_OF=y
CONFIG_VFP=y
CONFIG_VFPv3=y
CONFIG_WATCHDOG_CORE=y
CONFIG_XPS=y
CONFIG_XXHASH=y
CONFIG_XZ_DEC_ARM=y
CONFIG_XZ_DEC_BCJ=y
CONFIG_ZBOOT_ROM_BSS=0
CONFIG_ZBOOT_ROM_TEXT=0
CONFIG_ZLIB_DEFLATE=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZSTD_COMPRESS=y
CONFIG_ZSTD_DECOMPRESS=y

View file

@ -0,0 +1,71 @@
From 28d0ed88f536dd639adf1b0c7c08e04be3c8f294 Mon Sep 17 00:00:00 2001
From: Thomas Pedersen <twp@codeaurora.org>
Date: Mon, 16 May 2016 17:58:50 -0700
Subject: [PATCH 01/69] dtbindings: qcom_adm: Fix channel specifiers
Original patch from Andy Gross.
This patch removes the crci information from the dma
channel property. At least one client device requires
using more than one CRCI value for a channel. This does
not match the current binding and the crci information
needs to be removed.
Instead, the client device will provide this information
via other means.
Signed-off-by: Andy Gross <agross@codeaurora.org>
Signed-off-by: Thomas Pedersen <twp@codeaurora.org>
---
Documentation/devicetree/bindings/dma/qcom_adm.txt | 16 ++++++----------
1 file changed, 6 insertions(+), 10 deletions(-)
--- a/Documentation/devicetree/bindings/dma/qcom_adm.txt
+++ b/Documentation/devicetree/bindings/dma/qcom_adm.txt
@@ -4,8 +4,7 @@ Required properties:
- compatible: must contain "qcom,adm" for IPQ/APQ8064 and MSM8960
- reg: Address range for DMA registers
- interrupts: Should contain one interrupt shared by all channels
-- #dma-cells: must be <2>. First cell denotes the channel number. Second cell
- denotes CRCI (client rate control interface) flow control assignment.
+- #dma-cells: must be <1>. First cell denotes the channel number.
- clocks: Should contain the core clock and interface clock.
- clock-names: Must contain "core" for the core clock and "iface" for the
interface clock.
@@ -22,7 +21,7 @@ Example:
compatible = "qcom,adm";
reg = <0x18300000 0x100000>;
interrupts = <0 170 0>;
- #dma-cells = <2>;
+ #dma-cells = <1>;
clocks = <&gcc ADM0_CLK>, <&gcc ADM0_PBUS_CLK>;
clock-names = "core", "iface";
@@ -35,15 +34,12 @@ Example:
qcom,ee = <0>;
};
-DMA clients must use the format descripted in the dma.txt file, using a three
+DMA clients must use the format descripted in the dma.txt file, using a two
cell specifier for each channel.
-Each dmas request consists of 3 cells:
+Each dmas request consists of two cells:
1. phandle pointing to the DMA controller
2. channel number
- 3. CRCI assignment, if applicable. If no CRCI flow control is required, use 0.
- The CRCI is used for flow control. It identifies the peripheral device that
- is the source/destination for the transferred data.
Example:
@@ -55,7 +51,7 @@ Example:
cs-gpios = <&qcom_pinmux 20 0>;
- dmas = <&adm_dma 6 9>,
- <&adm_dma 5 10>;
+ dmas = <&adm_dma 6>,
+ <&adm_dma 5>;
dma-names = "rx", "tx";
};

View file

@ -0,0 +1,29 @@
From 48051ece78136e4235a2415a52797db56f8a4478 Mon Sep 17 00:00:00 2001
From: Mathieu Olivari <mathieu@codeaurora.org>
Date: Tue, 21 Apr 2015 19:09:07 -0700
Subject: [PATCH 33/69] ARM: qcom: automatically select PCI_DOMAINS if PCI is
enabled
If multiple PCIe devices are present in the system, the kernel will
panic at boot time when trying to scan the PCI buses. This happens on
IPQ806x based platforms, which has 3 PCIe ports.
Enabling this option allows the kernel to assign the pci-domains
according to the device-tree content. This allows multiple PCIe
controllers to coexist in the system.
Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
---
arch/arm/mach-qcom/Kconfig | 1 +
1 file changed, 1 insertion(+)
--- a/arch/arm/mach-qcom/Kconfig
+++ b/arch/arm/mach-qcom/Kconfig
@@ -7,6 +7,7 @@ menuconfig ARCH_QCOM
select ARM_AMBA
select PINCTRL
select QCOM_SCM if SMP
+ select PCI_DOMAINS if PCI
help
Support for Qualcomm's devicetree based systems.

View file

@ -0,0 +1,62 @@
From fa71139b55e114aa8c3c4823ff8ee7d49ee810d4 Mon Sep 17 00:00:00 2001
From: Mathieu Olivari <mathieu@codeaurora.org>
Date: Wed, 29 Apr 2015 15:21:46 -0700
Subject: [PATCH 60/69] HACK: arch: arm: force ZRELADDR on arch-qcom
ARCH_QCOM is using the ARCH_MULTIPLATFORM option, as now recommended
on most ARM architectures. This automatically calculate ZRELADDR by
masking PHYS_OFFSET with 0xf8000000.
However, on IPQ806x, the first ~20MB of RAM is reserved for the hardware
network accelerators, and the bootloader removes this section from the
layout passed from the ATAGS (when used).
For newer bootloader, when DT is used, this is not a problem, we just
reserve this memory in the device tree. But if the bootloader doesn't
have DT support, then ATAGS have to be used. In this case, the ARM
decompressor will position the kernel in this low mem, which will not be
in the RAM section mapped by the bootloader, which means the kernel will
freeze in the middle of the boot process trying to map the memory.
As a work around, this patch allows disabling AUTO_ZRELADDR when
ARCH_QCOM is selected. It makes the zImage usage possible on bootloaders
which don't support device-tree, which is the case on certain early
IPQ806x based designs.
Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
---
arch/arm/Kconfig | 2 +-
arch/arm/Makefile | 2 ++
arch/arm/mach-qcom/Makefile.boot | 1 +
3 files changed, 4 insertions(+), 1 deletion(-)
create mode 100644 arch/arm/mach-qcom/Makefile.boot
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -321,7 +321,7 @@ config ARCH_MULTIPLATFORM
select ARCH_SELECT_MEMORY_MODEL
select ARM_HAS_SG_CHAIN
select ARM_PATCH_PHYS_VIRT
- select AUTO_ZRELADDR
+ select AUTO_ZRELADDR if !ARCH_QCOM
select TIMER_OF
select COMMON_CLK
select GENERIC_CLOCKEVENTS
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -251,9 +251,11 @@ MACHINE := arch/arm/mach-$(word 1,$(mac
else
MACHINE :=
endif
+ifeq ($(CONFIG_ARCH_QCOM),)
ifeq ($(CONFIG_ARCH_MULTIPLATFORM),y)
MACHINE :=
endif
+endif
machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
platdirs := $(patsubst %,arch/arm/plat-%/,$(sort $(plat-y)))
--- /dev/null
+++ b/arch/arm/mach-qcom/Makefile.boot
@@ -0,0 +1 @@
+zreladdr-y+= 0x42208000

View file

@ -0,0 +1,210 @@
From 71270226b14733a4b1f2cde58ea9265caa50b38d Mon Sep 17 00:00:00 2001
From: Adrian Panella <ianchi74@outlook.com>
Date: Thu, 9 Mar 2017 09:37:17 +0100
Subject: [PATCH 67/69] generic: Mangle bootloader's kernel arguments
The command-line arguments provided by the boot loader will be
appended to a new device tree property: bootloader-args.
If there is a property "append-rootblock" in DT under /chosen
and a root= option in bootloaders command line it will be parsed
and added to DT bootargs with the form: <append-rootblock>XX.
Only command line ATAG will be processed, the rest of the ATAGs
sent by bootloader will be ignored.
This is usefull in dual boot systems, to get the current root partition
without afecting the rest of the system.
Signed-off-by: Adrian Panella <ianchi74@outlook.com>
---
arch/arm/Kconfig | 11 +++++
arch/arm/boot/compressed/atags_to_fdt.c | 72 ++++++++++++++++++++++++++++++++-
init/main.c | 16 ++++++++
3 files changed, 98 insertions(+), 1 deletion(-)
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1780,6 +1780,17 @@ config ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEN
The command-line arguments provided by the boot loader will be
appended to the the device tree bootargs property.
+config ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
+ bool "Append rootblock parsing bootloader's kernel arguments"
+ help
+ The command-line arguments provided by the boot loader will be
+ appended to a new device tree property: bootloader-args.
+ If there is a property "append-rootblock" in DT under /chosen
+ and a root= option in bootloaders command line it will be parsed
+ and added to DT bootargs with the form: <append-rootblock>XX.
+ Only command line ATAG will be processed, the rest of the ATAGs
+ sent by bootloader will be ignored.
+
endchoice
config CMDLINE
--- a/arch/arm/boot/compressed/atags_to_fdt.c
+++ b/arch/arm/boot/compressed/atags_to_fdt.c
@@ -5,6 +5,8 @@
#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND)
#define do_extend_cmdline 1
+#elif defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
+#define do_extend_cmdline 1
#else
#define do_extend_cmdline 0
#endif
@@ -69,6 +71,80 @@ static uint32_t get_cell_size(const void
return cell_size;
}
+#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
+/**
+ * taken from arch/x86/boot/string.c
+ * local_strstr - Find the first substring in a %NUL terminated string
+ * @s1: The string to be searched
+ * @s2: The string to search for
+ */
+static char *local_strstr(const char *s1, const char *s2)
+{
+ size_t l1, l2;
+
+ l2 = strlen(s2);
+ if (!l2)
+ return (char *)s1;
+ l1 = strlen(s1);
+ while (l1 >= l2) {
+ l1--;
+ if (!memcmp(s1, s2, l2))
+ return (char *)s1;
+ s1++;
+ }
+ return NULL;
+}
+
+static char *append_rootblock(char *dest, const char *str, int len, void *fdt)
+{
+ char *ptr, *end, *tmp;
+ char *root="root=";
+ char *find_rootblock;
+ int i, l;
+ const char *rootblock;
+
+ find_rootblock = getprop(fdt, "/chosen", "find-rootblock", &l);
+ if(!find_rootblock)
+ find_rootblock = root;
+
+ //ARM doesn't have __HAVE_ARCH_STRSTR, so it was copied from x86
+ ptr = local_strstr(str, find_rootblock);
+
+ if(!ptr)
+ return dest;
+
+ end = strchr(ptr, ' ');
+ end = end ? (end - 1) : (strchr(ptr, 0) - 1);
+
+ // Some boards ubi.mtd=XX,ZZZZ, so let's check for '," too.
+ tmp = strchr(ptr, ',');
+
+ if(tmp)
+ end = end < tmp ? end : tmp - 1;
+
+ //find partition number (assumes format root=/dev/mtdXX | /dev/mtdblockXX | yy:XX | ubi.mtd=XX,ZZZZ )
+ for( i = 0; end >= ptr && *end >= '0' && *end <= '9'; end--, i++);
+ ptr = end + 1;
+
+ /* if append-rootblock property is set use it to append to command line */
+ rootblock = getprop(fdt, "/chosen", "append-rootblock", &l);
+ if(rootblock != NULL) {
+ if(*dest != ' ') {
+ *dest = ' ';
+ dest++;
+ len++;
+ }
+ if (len + l + i <= COMMAND_LINE_SIZE) {
+ memcpy(dest, rootblock, l);
+ dest += l - 1;
+ memcpy(dest, ptr, i);
+ dest += i;
+ }
+ }
+ return dest;
+}
+#endif
+
static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline)
{
char cmdline[COMMAND_LINE_SIZE];
@@ -88,12 +164,21 @@ static void merge_fdt_bootargs(void *fdt
/* and append the ATAG_CMDLINE */
if (fdt_cmdline) {
+
+#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
+ //save original bootloader args
+ //and append ubi.mtd with root partition number to current cmdline
+ setprop_string(fdt, "/chosen", "bootloader-args", fdt_cmdline);
+ ptr = append_rootblock(ptr, fdt_cmdline, len, fdt);
+
+#else
len = strlen(fdt_cmdline);
if (ptr - cmdline + len + 2 < COMMAND_LINE_SIZE) {
*ptr++ = ' ';
memcpy(ptr, fdt_cmdline, len);
ptr += len;
}
+#endif
}
*ptr = '\0';
@@ -168,7 +253,9 @@ int atags_to_fdt(void *atag_list, void *
else
setprop_string(fdt, "/chosen", "bootargs",
atag->u.cmdline.cmdline);
- } else if (atag->hdr.tag == ATAG_MEM) {
+ }
+#ifndef CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
+ else if (atag->hdr.tag == ATAG_MEM) {
if (memcount >= sizeof(mem_reg_property)/4)
continue;
if (!atag->u.mem.size)
@@ -212,6 +299,10 @@ int atags_to_fdt(void *atag_list, void *
setprop(fdt, "/memory", "reg", mem_reg_property,
4 * memcount * memsize);
}
+#else
+
+ }
+#endif
return fdt_pack(fdt);
}
--- a/init/main.c
+++ b/init/main.c
@@ -110,6 +110,10 @@
#include <kunit/test.h>
+#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
+#include <linux/of.h>
+#endif
+
static int kernel_init(void *);
extern void init_IRQ(void);
@@ -905,6 +909,18 @@ asmlinkage __visible void __init __no_sa
pr_notice("Kernel command line: %s\n", saved_command_line);
/* parameters may set static keys */
jump_label_init();
+
+#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
+ //Show bootloader's original command line for reference
+ if(of_chosen) {
+ const char *prop = of_get_property(of_chosen, "bootloader-args", NULL);
+ if(prop)
+ pr_notice("Bootloader command line (ignored): %s\n", prop);
+ else
+ pr_notice("Bootloader command line not present\n");
+ }
+#endif
+
parse_early_param();
after_dashes = parse_args("Booting kernel",
static_command_line, __start___param,

View file

@ -0,0 +1,40 @@
From 8f68331e14dff9a101f2d0e1d6bec84a031f27ee Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Thu, 9 Mar 2017 11:03:18 +0100
Subject: [PATCH 69/69] arm: boot: add dts files
Signed-off-by: John Crispin <john@phrozen.org>
---
arch/arm/boot/dts/Makefile | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -907,9 +907,27 @@ dtb-$(CONFIG_ARCH_QCOM) += \
qcom-ipq4019-ap.dk04.1-c3.dtb \
qcom-ipq4019-ap.dk07.1-c1.dtb \
qcom-ipq4019-ap.dk07.1-c2.dtb \
+ qcom-ipq8062-wg2600hp3.dtb \
qcom-ipq8064-ap148.dtb \
qcom-ipq8064-rb3011.dtb \
+ qcom-ipq8064-c2600.dtb \
+ qcom-ipq8064-d7800.dtb \
+ qcom-ipq8064-db149.dtb \
+ qcom-ipq8064-ap161.dtb \
+ qcom-ipq8064-ea7500-v1.dtb \
+ qcom-ipq8064-ea8500.dtb \
+ qcom-ipq8064-g10.dtb \
+ qcom-ipq8064-r7500.dtb \
+ qcom-ipq8064-r7500v2.dtb \
+ qcom-ipq8064-unifi-ac-hd.dtb \
+ qcom-ipq8064-wg2600hp.dtb \
+ qcom-ipq8064-wpq864.dtb \
+ qcom-ipq8064-wxr-2533dhp.dtb \
+ qcom-ipq8065-nbg6817.dtb \
+ qcom-ipq8065-r7800.dtb \
+ qcom-ipq8065-rt4230w-rev6.dtb \
+ qcom-ipq8068-ecw5410.dtb \
qcom-msm8226-samsung-s3ve3g.dtb \
qcom-msm8660-surf.dtb \
qcom-msm8960-cdp.dtb \
qcom-msm8974-fairphone-fp2.dtb \

View file

@ -0,0 +1,77 @@
--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
@@ -128,6 +128,7 @@
gpio-ranges = <&qcom_pinmux 0 0 69>;
#gpio-cells = <2>;
interrupt-controller;
+ #address-cells = <0>;
#interrupt-cells = <2>;
interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
@@ -155,6 +156,7 @@
function = "pcie3_rst";
drive-strength = <12>;
bias-disable;
+ output-low;
};
};
@@ -190,6 +192,7 @@
intc: interrupt-controller@2000000 {
compatible = "qcom,msm-qgic2";
interrupt-controller;
+ #address-cells = <0>;
#interrupt-cells = <3>;
reg = <0x02000000 0x1000>,
<0x02002000 0x1000>;
@@ -630,10 +736,13 @@
tsens_calib_backup: calib_backup@410 {
reg = <0x410 0xb>;
};
+ speedbin_efuse: speedbin@0c0 {
+ reg = <0x0c0 0x4>;
+ };
};
gcc: clock-controller@900000 {
- compatible = "qcom,gcc-ipq8064";
+ compatible = "qcom,gcc-ipq8064", "syscon";
reg = <0x00900000 0x4000>;
#clock-cells = <1>;
#reset-cells = <1>;
@@ -722,7 +749,7 @@
gmac0: ethernet@37000000 {
device_type = "network";
- compatible = "qcom,ipq806x-gmac";
+ compatible = "qcom,ipq806x-gmac", "snps,dwmac";
reg = <0x37000000 0x200000>;
interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "macirq";
@@ -745,7 +772,7 @@
gmac1: ethernet@37200000 {
device_type = "network";
- compatible = "qcom,ipq806x-gmac";
+ compatible = "qcom,ipq806x-gmac", "snps,dwmac";
reg = <0x37200000 0x200000>;
interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "macirq";
@@ -768,7 +795,7 @@
gmac2: ethernet@37400000 {
device_type = "network";
- compatible = "qcom,ipq806x-gmac";
+ compatible = "qcom,ipq806x-gmac", "snps,dwmac";
reg = <0x37400000 0x200000>;
interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "macirq";
@@ -791,7 +818,7 @@
gmac3: ethernet@37600000 {
device_type = "network";
- compatible = "qcom,ipq806x-gmac";
+ compatible = "qcom,ipq806x-gmac", "snps,dwmac";
reg = <0x37600000 0x200000>;
interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "macirq";

View file

@ -0,0 +1,355 @@
--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
@@ -8,6 +8,8 @@
#include <dt-bindings/reset/qcom,gcc-ipq806x.h>
#include <dt-bindings/soc/qcom,gsbi.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/mfd/qcom-rpm.h>
+#include <dt-bindings/clock/qcom,rpmcc.h>
/ {
#address-cells = <1>;
@@ -28,6 +30,16 @@
next-level-cache = <&L2>;
qcom,acc = <&acc0>;
qcom,saw = <&saw0>;
+ clocks = <&kraitcc 0>, <&kraitcc 4>;
+ clock-names = "cpu", "l2";
+ clock-latency = <100000>;
+ cpu-supply = <&smb208_s2a>;
+ operating-points-v2 = <&opp_table0>;
+ voltage-tolerance = <5>;
+ cooling-min-state = <0>;
+ cooling-max-state = <10>;
+ #cooling-cells = <2>;
+ cpu-idle-states = <&CPU_SPC>;
};
cpu1: cpu@1 {
@@ -38,16 +50,130 @@
next-level-cache = <&L2>;
qcom,acc = <&acc1>;
qcom,saw = <&saw1>;
+ clocks = <&kraitcc 1>, <&kraitcc 4>;
+ clock-names = "cpu", "l2";
+ clock-latency = <100000>;
+ cpu-supply = <&smb208_s2b>;
+ operating-points-v2 = <&opp_table0>;
+ voltage-tolerance = <5>;
+ cooling-min-state = <0>;
+ cooling-max-state = <10>;
+ #cooling-cells = <2>;
+ cpu-idle-states = <&CPU_SPC>;
+ };
+
+ idle-states {
+ CPU_SPC: spc {
+ compatible = "qcom,idle-state-spc";
+ status = "disabled";
+ entry-latency-us = <400>;
+ exit-latency-us = <900>;
+ min-residency-us = <3000>;
+ };
};
+ };
- L2: l2-cache {
- compatible = "cache";
- cache-level = <2>;
+ opp_table_l2: opp_table_l2 {
+ compatible = "operating-points-v2";
+
+ opp-384000000 {
+ opp-hz = /bits/ 64 <384000000>;
+ opp-microvolt = <1100000>;
+ clock-latency-ns = <100000>;
+ opp-level = <0>;
+ };
+
+ opp-1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ opp-microvolt = <1100000>;
+ clock-latency-ns = <100000>;
+ opp-level = <1>;
+ };
+
+ opp-1200000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+ opp-microvolt = <1150000>;
+ clock-latency-ns = <100000>;
+ opp-level = <2>;
};
};
+ opp_table0: opp_table0 {
+ compatible = "operating-points-v2-kryo-cpu";
+ nvmem-cells = <&speedbin_efuse>;
+
+ /*
+ * Voltage thresholds are <target min max>
+ */
+ opp-384000000 {
+ opp-hz = /bits/ 64 <384000000>;
+ opp-microvolt-speed0-pvs0-v0 = <1000000 950000 1050000>;
+ opp-microvolt-speed0-pvs1-v0 = <925000 878750 971250>;
+ opp-microvolt-speed0-pvs2-v0 = <875000 831250 918750>;
+ opp-microvolt-speed0-pvs3-v0 = <800000 760000 840000>;
+ opp-supported-hw = <0x1>;
+ clock-latency-ns = <100000>;
+ opp-level = <0>;
+ };
+
+ opp-600000000 {
+ opp-hz = /bits/ 64 <600000000>;
+ opp-microvolt-speed0-pvs0-v0 = <1050000 997500 1102500>;
+ opp-microvolt-speed0-pvs1-v0 = <975000 926250 1023750>;
+ opp-microvolt-speed0-pvs2-v0 = <925000 878750 971250>;
+ opp-microvolt-speed0-pvs3-v0 = <850000 807500 892500>;
+ opp-supported-hw = <0x1>;
+ clock-latency-ns = <100000>;
+ opp-level = <1>;
+ };
+
+ opp-800000000 {
+ opp-hz = /bits/ 64 <800000000>;
+ opp-microvolt-speed0-pvs0-v0 = <1100000 1045000 1155000>;
+ opp-microvolt-speed0-pvs1-v0 = <1025000 973750 1076250>;
+ opp-microvolt-speed0-pvs2-v0 = <995000 945250 1044750>;
+ opp-microvolt-speed0-pvs3-v0 = <900000 855000 945000>;
+ opp-supported-hw = <0x1>;
+ clock-latency-ns = <100000>;
+ opp-level = <1>;
+ };
+
+ opp-1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ opp-microvolt-speed0-pvs0-v0 = <1150000 1092500 1207500>;
+ opp-microvolt-speed0-pvs1-v0 = <1075000 1021250 1128750>;
+ opp-microvolt-speed0-pvs2-v0 = <1025000 973750 1076250>;
+ opp-microvolt-speed0-pvs3-v0 = <950000 902500 997500>;
+ opp-supported-hw = <0x1>;
+ clock-latency-ns = <100000>;
+ opp-level = <1>;
+ };
+
+ opp-1200000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+ opp-microvolt-speed0-pvs0-v0 = <1200000 1140000 1260000>;
+ opp-microvolt-speed0-pvs1-v0 = <1125000 1068750 1181250>;
+ opp-microvolt-speed0-pvs2-v0 = <1075000 1021250 1128750>;
+ opp-microvolt-speed0-pvs3-v0 = <1000000 950000 1050000>;
+ opp-supported-hw = <0x1>;
+ clock-latency-ns = <100000>;
+ opp-level = <2>;
+ };
+
+ opp-1400000000 {
+ opp-hz = /bits/ 64 <1400000000>;
+ opp-microvolt-speed0-pvs0-v0 = <1250000 1187500 1312500>;
+ opp-microvolt-speed0-pvs1-v0 = <1175000 1116250 1233750>;
+ opp-microvolt-speed0-pvs2-v0 = <1125000 1068750 1181250>;
+ opp-microvolt-speed0-pvs3-v0 = <1050000 997500 1102500>;
+ opp-supported-hw = <0x1>;
+ clock-latency-ns = <100000>;
+ opp-level = <2>;
+ };
+ };
+
thermal-zones {
tsens_tz_sensor0 {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors = <&tsens 0>;
@@ -93,6 +441,15 @@
};
};
+ fab-scaling {
+ compatible = "qcom,fab-scaling";
+ clocks = <&rpmcc RPM_APPS_FABRIC_A_CLK>, <&rpmcc RPM_EBI1_A_CLK>;
+ clock-names = "apps-fab-clk", "ddr-fab-clk";
+ fab_freq_high = <533000000>;
+ fab_freq_nominal = <400000000>;
+ cpu_freq_threshold = <1000000000>;
+ };
+
firmware {
scm {
compatible = "qcom,scm-ipq806x", "qcom,scm";
@@ -120,6 +477,17 @@
reg-names = "lpass-lpaif";
};
+ L2: l2-cache {
+ compatible = "qcom,krait-cache", "cache";
+ cache-level = <2>;
+ qcom,saw = <&saw_l2>;
+
+ clocks = <&kraitcc 4>;
+ clock-names = "l2";
+ l2-supply = <&smb208_s1a>;
+ operating-points-v2 = <&opp_table_l2>;
+ };
+
qcom_pinmux: pinmux@800000 {
compatible = "qcom,ipq8064-pinctrl";
reg = <0x800000 0x4000>;
@@ -160,6 +589,15 @@
};
};
+ i2c4_pins: i2c4_pinmux {
+ mux {
+ pins = "gpio12", "gpio13";
+ function = "gsbi4";
+ drive-strength = <12>;
+ bias-disable;
+ };
+ };
+
spi_pins: spi_pins {
mux {
pins = "gpio18", "gpio19", "gpio21";
@@ -169,6 +607,28 @@
};
};
+
+ mdio0_pins: mdio0_pins {
+ mux {
+ pins = "gpio0", "gpio1";
+ function = "mdio";
+ drive-strength = <8>;
+ bias-disable;
+ };
+ };
+
+ rgmii2_pins: rgmii2_pins {
+ mux {
+ pins = "gpio27", "gpio28", "gpio29",
+ "gpio30", "gpio31", "gpio32",
+ "gpio51", "gpio52", "gpio59",
+ "gpio60", "gpio61", "gpio62";
+ function = "rgmii2";
+ drive-strength = <8>;
+ bias-disable;
+ };
+ };
+
leds_pins: leds_pins {
mux {
pins = "gpio7", "gpio8", "gpio9",
@@ -243,6 +739,22 @@
regulator;
};
+ kraitcc: clock-controller {
+ compatible = "qcom,krait-cc-v1";
+ #clock-cells = <1>;
+ };
+
+ saw_l2: regulator@02012000 {
+ compatible = "qcom,saw2", "syscon";
+ reg = <0x02012000 0x1000>;
+ regulator;
+ };
+
+ sic_non_secure: sic-non-secure@12100000 {
+ compatible = "syscon";
+ reg = <0x12100000 0x10000>;
+ };
+
gsbi2: gsbi@12480000 {
compatible = "qcom,gsbi-v1.0.0";
cell-index = <2>;
@@ -478,6 +985,11 @@
#reset-cells = <1>;
};
+ sfpb_mutex_block: syscon@1200600 {
+ compatible = "syscon";
+ reg = <0x01200600 0x100>;
+ };
+
pcie0: pci@1b500000 {
compatible = "qcom,pcie-ipq8064";
reg = <0x1b500000 0x1000
@@ -739,6 +1335,20 @@
status = "disabled";
};
+ mdio0: mdio@37000000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ compatible = "qcom,ipq8064-mdio", "syscon";
+ reg = <0x37000000 0x200000>;
+ resets = <&gcc GMAC_CORE1_RESET>;
+ reset-names = "stmmaceth";
+ clocks = <&gcc GMAC_CORE1_CLK>;
+ clock-names = "stmmaceth";
+
+ status = "disabled";
+ };
+
vsdcc_fixed: vsdcc-regulator {
compatible = "regulator-fixed";
regulator-name = "SDCC Power";
@@ -814,4 +1463,17 @@
};
};
};
+
+ sfpb_mutex: sfpb-mutex {
+ compatible = "qcom,sfpb-mutex";
+ syscon = <&sfpb_mutex_block 4 4>;
+
+ #hwlock-cells = <1>;
+ };
+
+ smem {
+ compatible = "qcom,smem";
+ memory-region = <&smem>;
+ hwlocks = <&sfpb_mutex 3>;
+ };
};
--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
@@ -1020,6 +1020,37 @@
compatible = "qcom,rpmcc-ipq806x", "qcom,rpmcc";
#clock-cells = <1>;
};
+ regulators {
+ compatible = "qcom,rpm-smb208-regulators";
+
+ smb208_s1a: s1a {
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1150000>;
+
+ qcom,switch-mode-frequency = <1200000>;
+ };
+
+ smb208_s1b: s1b {
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1150000>;
+
+ qcom,switch-mode-frequency = <1200000>;
+ };
+
+ smb208_s2a: s2a {
+ regulator-min-microvolt = < 800000>;
+ regulator-max-microvolt = <1250000>;
+
+ qcom,switch-mode-frequency = <1200000>;
+ };
+
+ smb208_s2b: s2b {
+ regulator-min-microvolt = < 800000>;
+ regulator-max-microvolt = <1250000>;
+
+ qcom,switch-mode-frequency = <1200000>;
+ };
+ };
};
tcsr: syscon@1a400000 {

View file

@ -0,0 +1,89 @@
This uses upstream qcom-ipq8064-v1.0.dtsi and modifies it by patches
instead of keeping a local version.
We drop partitions, LEDs and keys from the file as we will implement
them differently anyway.
--- a/arch/arm/boot/dts/qcom-ipq8064-v1.0.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq8064-v1.0.dtsi
@@ -42,16 +42,6 @@
#size-cells = <1>;
spi-max-frequency = <50000000>;
reg = <0>;
-
- partition@0 {
- label = "rootfs";
- reg = <0x0 0x1000000>;
- };
-
- partition@1 {
- label = "scratch";
- reg = <0x1000000 0x1000000>;
- };
};
};
};
@@ -64,64 +54,5 @@
ports-implemented = <0x1>;
status = "ok";
};
-
- gpio_keys {
- compatible = "gpio-keys";
- pinctrl-0 = <&buttons_pins>;
- pinctrl-names = "default";
-
- button@1 {
- label = "reset";
- linux,code = <KEY_RESTART>;
- gpios = <&qcom_pinmux 54 GPIO_ACTIVE_LOW>;
- linux,input-type = <1>;
- debounce-interval = <60>;
- };
- button@2 {
- label = "wps";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&qcom_pinmux 65 GPIO_ACTIVE_LOW>;
- linux,input-type = <1>;
- debounce-interval = <60>;
- };
- };
-
- leds {
- compatible = "gpio-leds";
- pinctrl-0 = <&leds_pins>;
- pinctrl-names = "default";
-
- led@7 {
- label = "led_usb1";
- gpios = <&qcom_pinmux 7 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "usbdev";
- default-state = "off";
- };
-
- led@8 {
- label = "led_usb3";
- gpios = <&qcom_pinmux 8 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "usbdev";
- default-state = "off";
- };
-
- led@9 {
- label = "status_led_fail";
- gpios = <&qcom_pinmux 9 GPIO_ACTIVE_HIGH>;
- default-state = "off";
- };
-
- led@26 {
- label = "sata_led";
- gpios = <&qcom_pinmux 26 GPIO_ACTIVE_HIGH>;
- default-state = "off";
- };
-
- led@53 {
- label = "status_led_pass";
- gpios = <&qcom_pinmux 53 GPIO_ACTIVE_HIGH>;
- default-state = "off";
- };
- };
};
};

View file

@ -0,0 +1,14 @@
This uses upstream qcom-ipq8064-v1.0.dtsi and modifies it by patches
instead of keeping a local version. This patch adds our local adjustments
for the (local) additional contents of qcom-ipq8064.dtsi
--- a/arch/arm/boot/dts/qcom-ipq8064-v1.0.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq8064-v1.0.dtsi
@@ -56,3 +56,7 @@
};
};
};
+
+&CPU_SPC {
+ status = "okay";
+};

View file

@ -0,0 +1,145 @@
--- a/arch/arm/boot/dts/qcom-ipq8064-rb3011.dts
+++ b/arch/arm/boot/dts/qcom-ipq8064-rb3011.dts
@@ -24,73 +24,6 @@
device_type = "memory";
};
- mdio0: mdio@0 {
- status = "okay";
- compatible = "virtual,mdio-gpio";
- gpios = <&qcom_pinmux 1 GPIO_ACTIVE_HIGH>,
- <&qcom_pinmux 0 GPIO_ACTIVE_HIGH>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- pinctrl-0 = <&mdio0_pins>;
- pinctrl-names = "default";
-
- switch0: switch@10 {
- compatible = "qca,qca8337";
- #address-cells = <1>;
- #size-cells = <0>;
-
- dsa,member = <0 0>;
-
- pinctrl-0 = <&sw0_reset_pin>;
- pinctrl-names = "default";
-
- reset-gpios = <&qcom_pinmux 16 GPIO_ACTIVE_LOW>;
- reg = <0x10>;
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- switch0cpu: port@0 {
- reg = <0>;
- label = "cpu";
- ethernet = <&gmac0>;
- phy-mode = "rgmii-id";
- fixed-link {
- speed = <1000>;
- full-duplex;
- };
- };
-
- port@1 {
- reg = <1>;
- label = "sw1";
- };
-
- port@2 {
- reg = <2>;
- label = "sw2";
- };
-
- port@3 {
- reg = <3>;
- label = "sw3";
- };
-
- port@4 {
- reg = <4>;
- label = "sw4";
- };
-
- port@5 {
- reg = <5>;
- label = "sw5";
- };
- };
- };
- };
-
mdio1: mdio@1 {
status = "okay";
compatible = "virtual,mdio-gpio";
@@ -216,6 +149,68 @@
};
};
+&mdio0 {
+ status = "okay";
+
+ pinctrl-0 = <&mdio0_pins>;
+ pinctrl-names = "default";
+
+ switch0: switch@10 {
+ compatible = "qca,qca8337";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dsa,member = <0 0>;
+
+ pinctrl-0 = <&sw0_reset_pin>;
+ pinctrl-names = "default";
+
+ reset-gpios = <&qcom_pinmux 16 GPIO_ACTIVE_LOW>;
+ reg = <0x10>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ switch0cpu: port@0 {
+ reg = <0>;
+ label = "cpu";
+ ethernet = <&gmac0>;
+ phy-mode = "rgmii-id";
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ label = "sw1";
+ };
+
+ port@2 {
+ reg = <2>;
+ label = "sw2";
+ };
+
+ port@3 {
+ reg = <3>;
+ label = "sw3";
+ };
+
+ port@4 {
+ reg = <4>;
+ label = "sw4";
+ };
+
+ port@5 {
+ reg = <5>;
+ label = "sw5";
+ };
+ };
+ };
+};
+
&gmac0 {
status = "okay";

View file

@ -0,0 +1,51 @@
From a206d4061f1cc2c5cd17ee45c53a0ba711e48e6d Mon Sep 17 00:00:00 2001
From: Ansuel Smith <ansuelsmth@gmail.com>
Date: Sun, 7 Feb 2021 16:42:52 +0100
Subject: [PATCH 3/3] drivers: cpufreq: qcom-cpufreq-nvmem: support specific
cpufreq driver
Add support for specific cpufreq driver for qcom-cpufreq-nvmem driver.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
drivers/cpufreq/qcom-cpufreq-nvmem.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
--- a/drivers/cpufreq/qcom-cpufreq-nvmem.c
+++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c
@@ -52,6 +52,7 @@ struct qcom_cpufreq_match_data {
char **pvs_name,
struct qcom_cpufreq_drv *drv);
const char **genpd_names;
+ const char *cpufreq_driver;
};
struct qcom_cpufreq_drv {
@@ -250,6 +251,7 @@ static const struct qcom_cpufreq_match_d
static const struct qcom_cpufreq_match_data match_data_krait = {
.get_version = qcom_cpufreq_krait_name_version,
+ .cpufreq_driver = "krait-cpufreq",
};
static const char *qcs404_genpd_names[] = { "cpr", NULL };
@@ -385,6 +387,19 @@ static int qcom_cpufreq_probe(struct pla
}
}
+ if (drv->data->cpufreq_driver) {
+ cpufreq_dt_pdev = platform_device_register_simple(
+ drv->data->cpufreq_driver, -1, NULL, 0);
+ if (!IS_ERR(cpufreq_dt_pdev)) {
+ platform_set_drvdata(pdev, drv);
+ return 0;
+ } else {
+ dev_err(cpu_dev,
+ "Failed to register dedicated %s cpufreq\n",
+ drv->data->cpufreq_driver);
+ }
+ }
+
cpufreq_dt_pdev = platform_device_register_simple("cpufreq-dt", -1,
NULL, 0);
if (!IS_ERR(cpufreq_dt_pdev)) {

View file

@ -0,0 +1,115 @@
From 0af44917941cbfecdc86bb9bf05ff01d22a88973 Mon Sep 17 00:00:00 2001
From: Ansuel Smith <ansuelsmth@gmail.com>
Date: Sun, 7 Feb 2021 16:52:56 +0100
Subject: [PATCH 1/4] ipq806x: gcc: add missing clk flag
Some flag are missing from the original code.
These clk can't be set using the protected-clock proprities as they
cause the malfunction of the serial interface.
These clks are needed for the rpm interface to work proprely or the
cpu regulators starts to fail as soon as they are disabled by the
kernel.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
drivers/clk/qcom/gcc-ipq806x.c | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
--- a/drivers/clk/qcom/gcc-ipq806x.c
+++ b/drivers/clk/qcom/gcc-ipq806x.c
@@ -65,6 +65,7 @@ static struct clk_pll pll3 = {
.parent_names = (const char *[]){ "pxo" },
.num_parents = 1,
.ops = &clk_pll_ops,
+ .flags = CLK_IS_CRITICAL,
},
};
@@ -782,7 +783,7 @@ static struct clk_rcg gsbi4_qup_src = {
.parent_names = gcc_pxo_pll8,
.num_parents = 2,
.ops = &clk_rcg_ops,
- .flags = CLK_SET_PARENT_GATE,
+ .flags = CLK_SET_PARENT_GATE | CLK_IGNORE_UNUSED,
},
},
};
@@ -798,7 +799,7 @@ static struct clk_branch gsbi4_qup_clk =
.parent_names = (const char *[]){ "gsbi4_qup_src" },
.num_parents = 1,
.ops = &clk_branch_ops,
- .flags = CLK_SET_RATE_PARENT,
+ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
},
},
};
@@ -880,7 +881,7 @@ static struct clk_rcg gsbi6_qup_src = {
.parent_names = gcc_pxo_pll8,
.num_parents = 2,
.ops = &clk_rcg_ops,
- .flags = CLK_SET_PARENT_GATE,
+ .flags = CLK_SET_PARENT_GATE | CLK_IGNORE_UNUSED,
},
},
};
@@ -945,7 +946,7 @@ static struct clk_branch gsbi7_qup_clk =
.parent_names = (const char *[]){ "gsbi7_qup_src" },
.num_parents = 1,
.ops = &clk_branch_ops,
- .flags = CLK_SET_RATE_PARENT,
+ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
},
},
};
@@ -991,6 +992,7 @@ static struct clk_branch gsbi4_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "gsbi4_h_clk",
.ops = &clk_branch_ops,
+ .flags = CLK_IGNORE_UNUSED,
},
},
};
@@ -1293,6 +1295,7 @@ static struct clk_rcg sdc1_src = {
.parent_names = gcc_pxo_pll8,
.num_parents = 2,
.ops = &clk_rcg_ops,
+ .flags = CLK_SET_RATE_GATE,
},
}
};
@@ -1341,6 +1344,7 @@ static struct clk_rcg sdc3_src = {
.parent_names = gcc_pxo_pll8,
.num_parents = 2,
.ops = &clk_rcg_ops,
+ .flags = CLK_SET_RATE_GATE,
},
}
};
@@ -1424,6 +1428,7 @@ static struct clk_rcg tsif_ref_src = {
.parent_names = gcc_pxo_pll8,
.num_parents = 2,
.ops = &clk_rcg_ops,
+ .flags = CLK_SET_RATE_GATE,
},
}
};
@@ -2694,7 +2699,8 @@ static struct clk_dyn_rcg ubi32_core1_sr
.parent_names = gcc_pxo_pll8_pll14_pll18_pll0,
.num_parents = 5,
.ops = &clk_dyn_rcg_ops,
- .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
+ .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE |
+ CLK_IGNORE_UNUSED,
},
},
};
@@ -2747,7 +2753,8 @@ static struct clk_dyn_rcg ubi32_core2_sr
.parent_names = gcc_pxo_pll8_pll14_pll18_pll0,
.num_parents = 5,
.ops = &clk_dyn_rcg_ops,
- .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
+ .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE |
+ CLK_IGNORE_UNUSED,
},
},
};

View file

@ -0,0 +1,59 @@
From 3a5f1793c0bf4a6b536751886b0a44589fe05f35 Mon Sep 17 00:00:00 2001
From: Ansuel Smith <ansuelsmth@gmail.com>
Date: Sun, 7 Feb 2021 17:00:07 +0100
Subject: [PATCH 2/4] ipq806x: lcc: add missing reset
Add missing reset for ipq806x lcc clk
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
drivers/clk/qcom/lcc-ipq806x.c | 8 ++++++++
include/dt-bindings/clock/qcom,lcc-ipq806x.h | 1 +
2 files changed, 9 insertions(+)
--- a/drivers/clk/qcom/lcc-ipq806x.c
+++ b/drivers/clk/qcom/lcc-ipq806x.c
@@ -12,6 +12,7 @@
#include <linux/of_device.h>
#include <linux/clk-provider.h>
#include <linux/regmap.h>
+#include <linux/reset-controller.h>
#include <dt-bindings/clock/qcom,lcc-ipq806x.h>
@@ -22,6 +23,7 @@
#include "clk-branch.h"
#include "clk-regmap-divider.h"
#include "clk-regmap-mux.h"
+#include "reset.h"
static struct clk_pll pll4 = {
.l_reg = 0x4,
@@ -39,6 +41,10 @@ static struct clk_pll pll4 = {
},
};
+static const struct qcom_reset_map lcc_ipq806x_resets[] = {
+ [LCC_PCM_RESET] = { 0x54, 13 },
+};
+
static const struct pll_config pll4_config = {
.l = 0xf,
.m = 0x91,
@@ -417,6 +423,8 @@ static const struct qcom_cc_desc lcc_ipq
.config = &lcc_ipq806x_regmap_config,
.clks = lcc_ipq806x_clks,
.num_clks = ARRAY_SIZE(lcc_ipq806x_clks),
+ .resets = lcc_ipq806x_resets,
+ .num_resets = ARRAY_SIZE(lcc_ipq806x_resets),
};
static const struct of_device_id lcc_ipq806x_match_table[] = {
--- a/include/dt-bindings/clock/qcom,lcc-ipq806x.h
+++ b/include/dt-bindings/clock/qcom,lcc-ipq806x.h
@@ -19,4 +19,5 @@
#define SPDIF_CLK 10
#define AHBIX_CLK 11
+#define LCC_PCM_RESET 0
#endif

View file

@ -0,0 +1,57 @@
From f8fdbecdaca97f0f2eebd77256e2eca4a8da6c39 Mon Sep 17 00:00:00 2001
From: Ansuel Smith <ansuelsmth@gmail.com>
Date: Sun, 7 Feb 2021 17:08:16 +0100
Subject: [PATCH 3/4] clk: qcom: krait: add missing enable disable
Add missing enable disable mux function. Add extra check to
div2_round_rate.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
drivers/clk/qcom/clk-krait.c | 27 +++++++++++++++++++++++++--
1 file changed, 25 insertions(+), 2 deletions(-)
--- a/drivers/clk/qcom/clk-krait.c
+++ b/drivers/clk/qcom/clk-krait.c
@@ -68,7 +68,25 @@ static u8 krait_mux_get_parent(struct cl
return clk_mux_val_to_index(hw, mux->parent_map, 0, sel);
}
+static int krait_mux_enable(struct clk_hw *hw)
+{
+ struct krait_mux_clk *mux = to_krait_mux_clk(hw);
+
+ __krait_mux_set_sel(mux, mux->en_mask);
+
+ return 0;
+}
+
+static void krait_mux_disable(struct clk_hw *hw)
+{
+ struct krait_mux_clk *mux = to_krait_mux_clk(hw);
+
+ __krait_mux_set_sel(mux, mux->safe_sel);
+}
+
const struct clk_ops krait_mux_clk_ops = {
+ .enable = krait_mux_enable,
+ .disable = krait_mux_disable,
.set_parent = krait_mux_set_parent,
.get_parent = krait_mux_get_parent,
.determine_rate = __clk_mux_determine_rate_closest,
@@ -79,8 +97,13 @@ EXPORT_SYMBOL_GPL(krait_mux_clk_ops);
static long krait_div2_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
{
- *parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), rate * 2);
- return DIV_ROUND_UP(*parent_rate, 2);
+ struct clk_hw *hw_parent = clk_hw_get_parent(hw);
+
+ if (hw_parent) {
+ *parent_rate = clk_hw_round_rate(hw_parent, rate * 2);
+ return DIV_ROUND_UP(*parent_rate, 2);
+ } else
+ return -1;
}
static int krait_div2_set_rate(struct clk_hw *hw, unsigned long rate,

View file

@ -0,0 +1,372 @@
From 22a0f55b0e505fbbbb680e451a62878bc97f7ff1 Mon Sep 17 00:00:00 2001
From: Ansuel Smith <ansuelsmth@gmail.com>
Date: Sun, 7 Feb 2021 17:23:38 +0100
Subject: [PATCH 4/4] ipq806x: gcc: add missing clk and reset for crypto engine
Add missing clk and reset needed for nss additional core and crypto
engine.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
drivers/clk/qcom/gcc-ipq806x.c | 250 +++++++++++++++++++
include/dt-bindings/clock/qcom,gcc-ipq806x.h | 5 +-
include/dt-bindings/reset/qcom,gcc-ipq806x.h | 5 +
3 files changed, 259 insertions(+), 1 deletion(-)
--- a/drivers/clk/qcom/gcc-ipq806x.c
+++ b/drivers/clk/qcom/gcc-ipq806x.c
@@ -223,7 +223,9 @@ static struct clk_regmap pll14_vote = {
static struct pll_freq_tbl pll18_freq_tbl[] = {
NSS_PLL_RATE(550000000, 44, 0, 1, 0x01495625),
+ NSS_PLL_RATE(600000000, 48, 0, 1, 0x01495625),
NSS_PLL_RATE(733000000, 58, 16, 25, 0x014b5625),
+ NSS_PLL_RATE(800000000, 64, 0, 1, 0x01495625),
};
static struct clk_pll pll18 = {
@@ -245,6 +247,22 @@ static struct clk_pll pll18 = {
},
};
+static struct clk_pll pll11 = {
+ .l_reg = 0x3184,
+ .m_reg = 0x3188,
+ .n_reg = 0x318c,
+ .config_reg = 0x3194,
+ .mode_reg = 0x3180,
+ .status_reg = 0x3198,
+ .status_bit = 16,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "pll11",
+ .parent_names = (const char *[]){ "pxo" },
+ .num_parents = 1,
+ .ops = &clk_pll_ops,
+ },
+};
+
enum {
P_PXO,
P_PLL8,
@@ -253,6 +271,7 @@ enum {
P_CXO,
P_PLL14,
P_PLL18,
+ P_PLL11,
};
static const struct parent_map gcc_pxo_pll8_map[] = {
@@ -320,6 +339,42 @@ static const char * const gcc_pxo_pll8_p
"pll18",
};
+static const struct parent_map gcc_pxo_pll8_pll0_pll14_pll18_pll11_map[] = {
+ { P_PXO, 0 },
+ { P_PLL8, 4 },
+ { P_PLL0, 2 },
+ { P_PLL14, 5 },
+ { P_PLL18, 1 },
+ { P_PLL11, 3 },
+};
+
+static const char *gcc_pxo_pll8_pll0_pll14_pll18_pll11[] = {
+ "pxo",
+ "pll8_vote",
+ "pll0_vote",
+ "pll14",
+ "pll18",
+ "pll11"
+};
+
+static const struct parent_map gcc_pxo_pll3_pll0_pll14_pll18_pll11_map[] = {
+ { P_PXO, 0 },
+ { P_PLL3, 6 },
+ { P_PLL0, 2 },
+ { P_PLL14, 5 },
+ { P_PLL18, 1 },
+ { P_PLL11, 3 },
+};
+
+static const char *gcc_pxo_pll3_pll0_pll14_pll18_pll11[] = {
+ "pxo",
+ "pll3",
+ "pll0_vote",
+ "pll14",
+ "pll18",
+ "pll11"
+};
+
static struct freq_tbl clk_tbl_gsbi_uart[] = {
{ 1843200, P_PLL8, 2, 6, 625 },
{ 3686400, P_PLL8, 2, 12, 625 },
@@ -1261,6 +1316,7 @@ static const struct freq_tbl clk_tbl_sdc
{ 20210000, P_PLL8, 1, 1, 19 },
{ 24000000, P_PLL8, 4, 1, 4 },
{ 48000000, P_PLL8, 4, 1, 2 },
+ { 52000000, P_PLL8, 1, 2, 15 }, /* 51.2 Mhz */
{ 64000000, P_PLL8, 3, 1, 2 },
{ 96000000, P_PLL8, 4, 0, 0 },
{ 192000000, P_PLL8, 2, 0, 0 },
@@ -2647,7 +2703,9 @@ static const struct freq_tbl clk_tbl_nss
{ 110000000, P_PLL18, 1, 1, 5 },
{ 275000000, P_PLL18, 2, 0, 0 },
{ 550000000, P_PLL18, 1, 0, 0 },
+ { 600000000, P_PLL18, 1, 0, 0 },
{ 733000000, P_PLL18, 1, 0, 0 },
+ { 800000000, P_PLL18, 1, 0, 0 },
{ }
};
@@ -2759,6 +2817,186 @@ static struct clk_dyn_rcg ubi32_core2_sr
},
};
+static const struct freq_tbl clk_tbl_ce5_core[] = {
+ { 150000000, P_PLL3, 8, 1, 1 },
+ { 213200000, P_PLL11, 5, 1, 1 },
+ { }
+};
+
+static struct clk_dyn_rcg ce5_core_src = {
+ .ns_reg[0] = 0x36C4,
+ .ns_reg[1] = 0x36C8,
+ .bank_reg = 0x36C0,
+ .s[0] = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll3_pll0_pll14_pll18_pll11_map,
+ },
+ .s[1] = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll3_pll0_pll14_pll18_pll11_map,
+ },
+ .p[0] = {
+ .pre_div_shift = 3,
+ .pre_div_width = 4,
+ },
+ .p[1] = {
+ .pre_div_shift = 3,
+ .pre_div_width = 4,
+ },
+ .mux_sel_bit = 0,
+ .freq_tbl = clk_tbl_ce5_core,
+ .clkr = {
+ .enable_reg = 0x36C0,
+ .enable_mask = BIT(1),
+ .hw.init = &(struct clk_init_data){
+ .name = "ce5_core_src",
+ .parent_names = gcc_pxo_pll3_pll0_pll14_pll18_pll11,
+ .num_parents = 6,
+ .ops = &clk_dyn_rcg_ops,
+ },
+ },
+};
+
+static struct clk_branch ce5_core_clk = {
+ .halt_reg = 0x2FDC,
+ .halt_bit = 5,
+ .hwcg_reg = 0x36CC,
+ .hwcg_bit = 6,
+ .clkr = {
+ .enable_reg = 0x36CC,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "ce5_core_clk",
+ .parent_names = (const char *[]){
+ "ce5_core_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static const struct freq_tbl clk_tbl_ce5_a_clk[] = {
+ { 160000000, P_PLL0, 5, 1, 1 },
+ { 213200000, P_PLL11, 5, 1, 1 },
+ { }
+};
+
+static struct clk_dyn_rcg ce5_a_clk_src = {
+ .ns_reg[0] = 0x3d84,
+ .ns_reg[1] = 0x3d88,
+ .bank_reg = 0x3d80,
+ .s[0] = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll8_pll0_pll14_pll18_pll11_map,
+ },
+ .s[1] = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll8_pll0_pll14_pll18_pll11_map,
+ },
+ .p[0] = {
+ .pre_div_shift = 3,
+ .pre_div_width = 4,
+ },
+ .p[1] = {
+ .pre_div_shift = 3,
+ .pre_div_width = 4,
+ },
+ .mux_sel_bit = 0,
+ .freq_tbl = clk_tbl_ce5_a_clk,
+ .clkr = {
+ .enable_reg = 0x3d80,
+ .enable_mask = BIT(1),
+ .hw.init = &(struct clk_init_data){
+ .name = "ce5_a_clk_src",
+ .parent_names = gcc_pxo_pll8_pll0_pll14_pll18_pll11,
+ .num_parents = 6,
+ .ops = &clk_dyn_rcg_ops,
+ },
+ },
+};
+
+static struct clk_branch ce5_a_clk = {
+ .halt_reg = 0x3c20,
+ .halt_bit = 12,
+ .hwcg_reg = 0x3d8c,
+ .hwcg_bit = 6,
+ .clkr = {
+ .enable_reg = 0x3d8c,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "ce5_a_clk",
+ .parent_names = (const char *[]){
+ "ce5_a_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static const struct freq_tbl clk_tbl_ce5_h_clk[] = {
+ { 160000000, P_PLL0, 5, 1, 1 },
+ { 213200000, P_PLL11, 5, 1, 1 },
+ { }
+};
+
+static struct clk_dyn_rcg ce5_h_clk_src = {
+ .ns_reg[0] = 0x3c64,
+ .ns_reg[1] = 0x3c68,
+ .bank_reg = 0x3c60,
+ .s[0] = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll8_pll0_pll14_pll18_pll11_map,
+ },
+ .s[1] = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll8_pll0_pll14_pll18_pll11_map,
+ },
+ .p[0] = {
+ .pre_div_shift = 3,
+ .pre_div_width = 4,
+ },
+ .p[1] = {
+ .pre_div_shift = 3,
+ .pre_div_width = 4,
+ },
+ .mux_sel_bit = 0,
+ .freq_tbl = clk_tbl_ce5_h_clk,
+ .clkr = {
+ .enable_reg = 0x3c60,
+ .enable_mask = BIT(1),
+ .hw.init = &(struct clk_init_data){
+ .name = "ce5_h_clk_src",
+ .parent_names = gcc_pxo_pll8_pll0_pll14_pll18_pll11,
+ .num_parents = 6,
+ .ops = &clk_dyn_rcg_ops,
+ },
+ },
+};
+
+static struct clk_branch ce5_h_clk = {
+ .halt_reg = 0x3c20,
+ .halt_bit = 11,
+ .hwcg_reg = 0x3c6c,
+ .hwcg_bit = 6,
+ .clkr = {
+ .enable_reg = 0x3c6c,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "ce5_h_clk",
+ .parent_names = (const char *[]){
+ "ce5_h_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
static struct clk_regmap *gcc_ipq806x_clks[] = {
[PLL0] = &pll0.clkr,
[PLL0_VOTE] = &pll0_vote,
@@ -2766,6 +3004,7 @@ static struct clk_regmap *gcc_ipq806x_cl
[PLL4_VOTE] = &pll4_vote,
[PLL8] = &pll8.clkr,
[PLL8_VOTE] = &pll8_vote,
+ [PLL11] = &pll11.clkr,
[PLL14] = &pll14.clkr,
[PLL14_VOTE] = &pll14_vote,
[PLL18] = &pll18.clkr,
@@ -2880,6 +3119,12 @@ static struct clk_regmap *gcc_ipq806x_cl
[PLL9] = &hfpll0.clkr,
[PLL10] = &hfpll1.clkr,
[PLL12] = &hfpll_l2.clkr,
+ [CE5_A_CLK_SRC] = &ce5_a_clk_src.clkr,
+ [CE5_A_CLK] = &ce5_a_clk.clkr,
+ [CE5_H_CLK_SRC] = &ce5_h_clk_src.clkr,
+ [CE5_H_CLK] = &ce5_h_clk.clkr,
+ [CE5_CORE_CLK_SRC] = &ce5_core_src.clkr,
+ [CE5_CORE_CLK] = &ce5_core_clk.clkr,
};
static const struct qcom_reset_map gcc_ipq806x_resets[] = {
@@ -3011,6 +3256,11 @@ static const struct qcom_reset_map gcc_i
[GMAC_CORE3_RESET] = { 0x3cfc, 0 },
[GMAC_CORE4_RESET] = { 0x3d1c, 0 },
[GMAC_AHB_RESET] = { 0x3e24, 0 },
+ [CRYPTO_ENG1_RESET] = { 0x3e00, 0},
+ [CRYPTO_ENG2_RESET] = { 0x3e04, 0},
+ [CRYPTO_ENG3_RESET] = { 0x3e08, 0},
+ [CRYPTO_ENG4_RESET] = { 0x3e0c, 0},
+ [CRYPTO_AHB_RESET] = { 0x3e10, 0},
[NSS_CH0_RST_RX_CLK_N_RESET] = { 0x3b60, 0 },
[NSS_CH0_RST_TX_CLK_N_RESET] = { 0x3b60, 1 },
[NSS_CH0_RST_RX_125M_N_RESET] = { 0x3b60, 2 },
--- a/include/dt-bindings/clock/qcom,gcc-ipq806x.h
+++ b/include/dt-bindings/clock/qcom,gcc-ipq806x.h
@@ -240,7 +240,7 @@
#define PLL14 232
#define PLL14_VOTE 233
#define PLL18 234
-#define CE5_SRC 235
+#define CE5_A_CLK 235
#define CE5_H_CLK 236
#define CE5_CORE_CLK 237
#define CE3_SLEEP_CLK 238
@@ -283,5 +283,8 @@
#define EBI2_AON_CLK 281
#define NSSTCM_CLK_SRC 282
#define NSSTCM_CLK 283
+#define CE5_A_CLK_SRC 285
+#define CE5_H_CLK_SRC 286
+#define CE5_CORE_CLK_SRC 287
#endif
--- a/include/dt-bindings/reset/qcom,gcc-ipq806x.h
+++ b/include/dt-bindings/reset/qcom,gcc-ipq806x.h
@@ -163,5 +163,10 @@
#define NSS_CAL_PRBS_RST_N_RESET 154
#define NSS_LCKDT_RST_N_RESET 155
#define NSS_SRDS_N_RESET 156
+#define CRYPTO_ENG1_RESET 157
+#define CRYPTO_ENG2_RESET 158
+#define CRYPTO_ENG3_RESET 159
+#define CRYPTO_ENG4_RESET 160
+#define CRYPTO_AHB_RESET 161
#endif

View file

@ -0,0 +1,237 @@
From c9ecd920324a647bf1f2b47f771c8f599cc7b551 Mon Sep 17 00:00:00 2001
From: Ansuel Smith <ansuelsmth@gmail.com>
Date: Sat, 22 Feb 2020 18:02:17 +0100
Subject: [PATCH 2/8] Documentation: cpufreq: add qcom,krait-cache bindings
Document dedicated cpufreq for Krait CPUs.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
.../bindings/cpufreq/qcom-cpufreq-krait.yaml | 221 ++++++++++++++++++
1 file changed, 221 insertions(+)
create mode 100644 Documentation/devicetree/bindings/cpufreq/qcom-cpufreq-krait.yaml
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpufreq/qcom-cpufreq-krait.yaml
@@ -0,0 +1,221 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/cpufreq/qcom-cpufreq-krait.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: CPU Frequency scaling driver for Krait SoCs
+
+maintainers:
+ - Ansuel Smith <ansuelsmth@gmail.com>
+
+description: |
+ The krait cpufreq driver is a dedicated frequency scaling driver
+ based on cpufreq-dt generic driver that scale L2 cache and the
+ cores. TEST
+
+ The L2 cache is scaled based on the max clk across all cores and
+ the clock is decided based on the opp-level set in the device tree.
+
+ Different core freq can be linked to a specific l2 freq and the driver
+ on frequency change will scale the core and the l2 clk based of the
+ linked freq.
+
+ On Krait SoC is present a bug and on every L2 clk change the driver
+ needs to set the clk to the idle freq before changing it to the new value.
+
+ This requires the qcom cpufreq nvmem driver to parse the different opp
+ core clk and an additional opp table for the l2 scaling.
+
+ If the driver detect broken config (for example missing opp-level) the
+ cpufreq driver skips the l2 scaling
+
+ Referring to this example opp-level can be used to link a range of cpu freq
+ to a specific l2 freq:
+ cpu opp freq 384000000 has opp-level 0
+ l2 opp freq 384000000 has opp-level 0
+ The driver will scale l2 to 384000000
+
+ cpu opp freq 600000000-1000000000 has opp-level 1
+ l2 opp freq 1000000000 has opp-level 1
+ The driver will scale l2 to 1000000000
+
+allOf:
+ - $ref: /schemas/cache-controller.yaml#
+
+select:
+ properties:
+ compatible:
+ items:
+ - enum:
+ - qcom,krait-cache
+
+ required:
+ - compatible
+
+properties:
+ compatible:
+ items:
+ - const: qcom,krait-cache
+ - const: cache
+
+ cache-level:
+ const: 2
+
+ clocks:
+ maxItems: 1
+
+ clock-names:
+ const: l2
+
+ l2-supply: true
+
+ operating-points-v2: true
+
+required:
+ - compatible
+ - cache-level
+ - clocks
+ - clock-names
+ - l2-supply
+ - operating-points-v2
+
+additionalProperties: false
+
+examples:
+ - |
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ compatible = "qcom,krait";
+ enable-method = "qcom,kpss-acc-v1";
+ device_type = "cpu";
+ reg = <0>;
+ next-level-cache = <&L2>;
+ qcom,acc = <&acc0>;
+ qcom,saw = <&saw0>;
+ clocks = <&kraitcc 0>, <&kraitcc 4>;
+ clock-names = "cpu", "l2";
+ clock-latency = <100000>;
+ cpu-supply = <&smb208_s2a>;
+ operating-points-v2 = <&opp_table0>;
+ voltage-tolerance = <5>;
+ cooling-min-state = <0>;
+ cooling-max-state = <10>;
+ #cooling-cells = <2>;
+ cpu-idle-states = <&CPU_SPC>;
+ };
+
+ /* ... */
+
+ };
+
+ opp_table0: opp_table0 {
+ compatible = "operating-points-v2-kryo-cpu";
+ nvmem-cells = <&speedbin_efuse>;
+
+ opp-384000000 {
+ opp-hz = /bits/ 64 <384000000>;
+ opp-microvolt-speed0-pvs0-v0 = <1000000>;
+ opp-microvolt-speed0-pvs1-v0 = <925000>;
+ opp-microvolt-speed0-pvs2-v0 = <875000>;
+ opp-microvolt-speed0-pvs3-v0 = <800000>;
+ opp-supported-hw = <0x1>;
+ clock-latency-ns = <100000>;
+ opp-level = <0>;
+ };
+
+ opp-600000000 {
+ opp-hz = /bits/ 64 <600000000>;
+ opp-microvolt-speed0-pvs0-v0 = <1050000>;
+ opp-microvolt-speed0-pvs1-v0 = <975000>;
+ opp-microvolt-speed0-pvs2-v0 = <925000>;
+ opp-microvolt-speed0-pvs3-v0 = <850000>;
+ opp-supported-hw = <0x1>;
+ clock-latency-ns = <100000>;
+ opp-level = <1>;
+ };
+
+ opp-800000000 {
+ opp-hz = /bits/ 64 <800000000>;
+ opp-microvolt-speed0-pvs0-v0 = <1100000>;
+ opp-microvolt-speed0-pvs1-v0 = <1025000>;
+ opp-microvolt-speed0-pvs2-v0 = <995000>;
+ opp-microvolt-speed0-pvs3-v0 = <900000>;
+ opp-supported-hw = <0x1>;
+ clock-latency-ns = <100000>;
+ opp-level = <1>;
+ };
+
+ opp-1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ opp-microvolt-speed0-pvs0-v0 = <1150000>;
+ opp-microvolt-speed0-pvs1-v0 = <1075000>;
+ opp-microvolt-speed0-pvs2-v0 = <1025000>;
+ opp-microvolt-speed0-pvs3-v0 = <950000>;
+ opp-supported-hw = <0x1>;
+ clock-latency-ns = <100000>;
+ opp-level = <1>;
+ };
+
+ opp-1200000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+ opp-microvolt-speed0-pvs0-v0 = <1200000>;
+ opp-microvolt-speed0-pvs1-v0 = <1125000>;
+ opp-microvolt-speed0-pvs2-v0 = <1075000>;
+ opp-microvolt-speed0-pvs3-v0 = <1000000>;
+ opp-supported-hw = <0x1>;
+ clock-latency-ns = <100000>;
+ opp-level = <2>;
+ };
+
+ opp-1400000000 {
+ opp-hz = /bits/ 64 <1400000000>;
+ opp-microvolt-speed0-pvs0-v0 = <1250000>;
+ opp-microvolt-speed0-pvs1-v0 = <1175000>;
+ opp-microvolt-speed0-pvs2-v0 = <1125000>;
+ opp-microvolt-speed0-pvs3-v0 = <1050000>;
+ opp-supported-hw = <0x1>;
+ clock-latency-ns = <100000>;
+ opp-level = <2>;
+ };
+ };
+
+ opp_table_l2: opp_table_l2 {
+ compatible = "operating-points-v2";
+
+ opp-384000000 {
+ opp-hz = /bits/ 64 <384000000>;
+ opp-microvolt = <1100000>;
+ clock-latency-ns = <100000>;
+ opp-level = <0>;
+ };
+ opp-1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ opp-microvolt = <1100000>;
+ clock-latency-ns = <100000>;
+ opp-level = <1>;
+ };
+ opp-1200000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+ opp-microvolt = <1150000>;
+ clock-latency-ns = <100000>;
+ opp-level = <2>;
+ };
+ };
+
+ soc {
+ L2: l2-cache {
+ compatible = "qcom,krait-cache", "cache";
+ cache-level = <2>;
+
+ clocks = <&kraitcc 4>;
+ clock-names = "l2";
+ l2-supply = <&smb208_s1a>;
+ operating-points-v2 = <&opp_table_l2>;
+ };
+ };
+
+...

View file

@ -0,0 +1,83 @@
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
@@ -64,6 +64,17 @@
#define NSS_COMMON_CLK_DIV_SGMII_100 4
#define NSS_COMMON_CLK_DIV_SGMII_10 49
+#define QSGMII_PCS_ALL_CH_CTL 0x80
+#define QSGMII_PCS_CH_SPEED_FORCE 0x2
+#define QSGMII_PCS_CH_SPEED_10 0x0
+#define QSGMII_PCS_CH_SPEED_100 0x4
+#define QSGMII_PCS_CH_SPEED_1000 0x8
+#define QSGMII_PCS_CH_SPEED_MASK (QSGMII_PCS_CH_SPEED_FORCE | \
+ QSGMII_PCS_CH_SPEED_10 | \
+ QSGMII_PCS_CH_SPEED_100 | \
+ QSGMII_PCS_CH_SPEED_1000)
+#define QSGMII_PCS_CH_SPEED_SHIFT(x) (x * 4)
+
#define QSGMII_PCS_CAL_LCKDT_CTL 0x120
#define QSGMII_PCS_CAL_LCKDT_CTL_RST BIT(19)
@@ -242,6 +253,36 @@ static void ipq806x_gmac_fix_mac_speed(v
ipq806x_gmac_set_speed(gmac, speed);
}
+static int
+ipq806x_gmac_get_qsgmii_pcs_speed_val(struct platform_device *pdev) {
+ struct device_node *fixed_link_node;
+ int rv;
+ int fixed_link_speed;
+
+ if (!of_phy_is_fixed_link(pdev->dev.of_node))
+ return 0;
+
+ fixed_link_node = of_get_child_by_name(pdev->dev.of_node, "fixed-link");
+ if (!fixed_link_node)
+ return -1;
+
+ rv = of_property_read_u32(fixed_link_node, "speed", &fixed_link_speed);
+ of_node_put(fixed_link_node);
+ if (rv)
+ return -1;
+
+ switch (fixed_link_speed) {
+ case SPEED_1000:
+ return QSGMII_PCS_CH_SPEED_FORCE | QSGMII_PCS_CH_SPEED_1000;
+ case SPEED_100:
+ return QSGMII_PCS_CH_SPEED_FORCE | QSGMII_PCS_CH_SPEED_100;
+ case SPEED_10:
+ return QSGMII_PCS_CH_SPEED_FORCE | QSGMII_PCS_CH_SPEED_10;
+ }
+
+ return -1;
+}
+
static int ipq806x_gmac_probe(struct platform_device *pdev)
{
struct plat_stmmacenet_data *plat_dat;
@@ -250,6 +291,7 @@ static int ipq806x_gmac_probe(struct pla
struct ipq806x_gmac *gmac;
int val;
int err;
+ int qsgmii_pcs_speed;
val = stmmac_get_platform_resources(pdev, &stmmac_res);
if (val)
@@ -346,6 +388,17 @@ static int ipq806x_gmac_probe(struct pla
0x1ul << QSGMII_PHY_RX_INPUT_EQU_OFFSET |
0x2ul << QSGMII_PHY_CDR_PI_SLEW_OFFSET |
0xCul << QSGMII_PHY_TX_DRV_AMP_OFFSET);
+
+ qsgmii_pcs_speed = ipq806x_gmac_get_qsgmii_pcs_speed_val(pdev);
+ if (qsgmii_pcs_speed != -1) {
+ regmap_update_bits(
+ gmac->qsgmii_csr,
+ QSGMII_PCS_ALL_CH_CTL,
+ QSGMII_PCS_CH_SPEED_MASK <<
+ QSGMII_PCS_CH_SPEED_SHIFT(gmac->id),
+ qsgmii_pcs_speed <<
+ QSGMII_PCS_CH_SPEED_SHIFT(gmac->id));
+ }
}
plat_dat->has_gmac = true;

View file

@ -0,0 +1,24 @@
From 5001f2e1a325b68dbf225bd17f69a4d3d975cca5 Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Thu, 9 Mar 2017 09:31:44 +0100
Subject: [PATCH 61/69] mtd: "rootfs" conflicts with OpenWrt auto mounting
Signed-off-by: John Crispin <john@phrozen.org>
---
drivers/mtd/parsers/qcomsmempart.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/mtd/parsers/qcomsmempart.c
+++ b/drivers/mtd/parsers/qcomsmempart.c
@@ -132,6 +132,11 @@ static int parse_qcomsmem_part(struct mt
parts[i].offset = le32_to_cpu(pentry->offset) * mtd->erasesize;
parts[i].mask_flags = pentry->attr;
parts[i].size = le32_to_cpu(pentry->length) * mtd->erasesize;
+
+ /* "rootfs" conflicts with OpenWrt auto mounting */
+ if (mtd_type_is_nand(mtd) && !strcmp(name, "rootfs"))
+ parts[i].name = "ubi";
+
pr_debug("%d: %s offs=0x%08x size=0x%08x attr:0x%08x\n",
i, pentry->name, le32_to_cpu(pentry->offset),
le32_to_cpu(pentry->length), pentry->attr);

View file

@ -0,0 +1,46 @@
From 84909e85881d67244240c9f40974ce12a51e3886 Mon Sep 17 00:00:00 2001
From: Ansuel Smith <ansuelsmth@gmail.com>
Date: Tue, 11 May 2021 23:09:45 +0200
Subject: [PATCH] ARM: dts: qcom: reduce pci IO size to 64K
The current value is probably a typo and is actually uncommon to find
1MB IO space even on a x86 arch. Also with recent changes to the pci
driver, pci1 and pci2 now fails to function as any connected device
fails any reg read/write. Reduce this to 64K as it should be more than
enough and 3 * 64K of total IO space doesn't exceed the IO_SPACE_LIMIT
hardcoded for the ARM arch.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
arch/arm/boot/dts/qcom-ipq8064.dtsi | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
@@ -1088,7 +1088,7 @@
#address-cells = <3>;
#size-cells = <2>;
- ranges = <0x81000000 0 0x0fe00000 0x0fe00000 0 0x00100000 /* downstream I/O */
+ ranges = <0x81000000 0 0x0fe00000 0x0fe00000 0 0x00010000 /* downstream I/O */
0x82000000 0 0x08000000 0x08000000 0 0x07e00000>; /* non-prefetchable memory */
interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
@@ -1139,7 +1139,7 @@
#address-cells = <3>;
#size-cells = <2>;
- ranges = <0x81000000 0 0x31e00000 0x31e00000 0 0x00100000 /* downstream I/O */
+ ranges = <0x81000000 0 0x31e00000 0x31e00000 0 0x00010000 /* downstream I/O */
0x82000000 0 0x2e000000 0x2e000000 0 0x03e00000>; /* non-prefetchable memory */
interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
@@ -1190,7 +1190,7 @@
#address-cells = <3>;
#size-cells = <2>;
- ranges = <0x81000000 0 0x35e00000 0x35e00000 0 0x00100000 /* downstream I/O */
+ ranges = <0x81000000 0 0x35e00000 0x35e00000 0 0x00010000 /* downstream I/O */
0x82000000 0 0x32000000 0x32000000 0 0x03e00000>; /* non-prefetchable memory */
interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;

View file

@ -0,0 +1,41 @@
From 8f32d48a309246a80bdca505968085a484d54408 Mon Sep 17 00:00:00 2001
From: Ansuel Smith <ansuelsmth@gmail.com>
Date: Mon, 19 Apr 2021 03:01:53 +0200
Subject: [thermal-next PATCH v2 1/2] thermal: qcom: tsens: init debugfs only with
successful probe
calibrate and tsens_register can fail or PROBE_DEFER. This will cause a
double or a wrong init of the debugfs information. Init debugfs only
with successful probe fixing warning about directory already present.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
Acked-by: Thara Gopinath <thara.gopinath@linaro.org>
---
drivers/thermal/qcom/tsens.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -918,8 +918,6 @@ int __init init_common(struct tsens_priv
if (tsens_version(priv) >= VER_0_1)
tsens_enable_irq(priv);
- tsens_debug_init(op);
-
err_put_device:
put_device(&op->dev);
return ret;
@@ -1155,7 +1153,12 @@ static int tsens_probe(struct platform_d
}
}
- return tsens_register(priv);
+ ret = tsens_register(priv);
+
+ if (!ret)
+ tsens_debug_init(pdev);
+
+ return ret;
}
static int tsens_remove(struct platform_device *pdev)

View file

@ -0,0 +1,54 @@
From 4204f22060f7a5d42c6ccb4d4c25a6a875571099 Mon Sep 17 00:00:00 2001
From: Ansuel Smith <ansuelsmth@gmail.com>
Date: Mon, 19 Apr 2021 03:08:37 +0200
Subject: [thermal-next PATCH v2 2/2] thermal: qcom: tsens: simplify debugfs init
function
Simplify debugfs init function.
- Add check for existing dev directory.
- Fix wrong version in dbg_version_show (with version 0.0.0, 0.1.0 was
incorrectly reported)
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
Reviewed-by: Thara Gopinath <thara.gopinath@linaro.org>
---
drivers/thermal/qcom/tsens.c | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -692,7 +692,7 @@ static int dbg_version_show(struct seq_f
return ret;
seq_printf(s, "%d.%d.%d\n", maj_ver, min_ver, step_ver);
} else {
- seq_puts(s, "0.1.0\n");
+ seq_printf(s, "0.%d.0\n", priv->feat->ver_major);
}
return 0;
@@ -704,21 +704,17 @@ DEFINE_SHOW_ATTRIBUTE(dbg_sensors);
static void tsens_debug_init(struct platform_device *pdev)
{
struct tsens_priv *priv = platform_get_drvdata(pdev);
- struct dentry *root, *file;
- root = debugfs_lookup("tsens", NULL);
- if (!root)
+ priv->debug_root = debugfs_lookup("tsens", NULL);
+ if (!priv->debug_root)
priv->debug_root = debugfs_create_dir("tsens", NULL);
- else
- priv->debug_root = root;
- file = debugfs_lookup("version", priv->debug_root);
- if (!file)
+ if (!debugfs_lookup("version", priv->debug_root))
debugfs_create_file("version", 0444, priv->debug_root,
pdev, &dbg_version_fops);
/* A directory for each instance of the TSENS IP */
- priv->debug = debugfs_create_dir(dev_name(&pdev->dev), priv->debug_root);
+ priv->debug = debugfs_lookup(dev_name(&pdev->dev), priv->debug_root);
debugfs_create_file("sensors", 0444, priv->debug, pdev, &dbg_sensors_fops);
}
#else

View file

@ -0,0 +1,121 @@
From: Christian Lamparter <chunkeey@googlemail.com>
Subject: SoC: add qualcomm syscon
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_QCOM_SMP2P) += smp2p.o
obj-$(CONFIG_QCOM_SMSM) += smsm.o
obj-$(CONFIG_QCOM_SOCINFO) += socinfo.o
obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o
+obj-$(CONFIG_QCOM_TCSR) += qcom_tcsr.o
obj-$(CONFIG_QCOM_APR) += apr.o
obj-$(CONFIG_QCOM_LLCC) += llcc-qcom.o
obj-$(CONFIG_QCOM_RPMHPD) += rpmhpd.o
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -189,6 +189,13 @@ config QCOM_SOCINFO
Say yes here to support the Qualcomm socinfo driver, providing
information about the SoC to user space.
+config QCOM_TCSR
+ tristate "QCOM Top Control and Status Registers"
+ depends on ARCH_QCOM
+ help
+ Say y here to enable TCSR support. The TCSR provides control
+ functions for various peripherals.
+
config QCOM_WCNSS_CTRL
tristate "Qualcomm WCNSS control driver"
depends on ARCH_QCOM || COMPILE_TEST
--- /dev/null
+++ b/drivers/soc/qcom/qcom_tcsr.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2014, The Linux foundation. 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 rev 2 and
+ * only rev 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 <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+
+#define TCSR_USB_PORT_SEL 0xb0
+
+static int tcsr_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ const struct device_node *node = pdev->dev.of_node;
+ void __iomem *base;
+ u32 val;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ if (!of_property_read_u32(node, "qcom,usb-ctrl-select", &val)) {
+ dev_err(&pdev->dev, "setting usb port select = %d\n", val);
+ writel(val, base + TCSR_USB_PORT_SEL);
+ }
+
+ return 0;
+}
+
+static const struct of_device_id tcsr_dt_match[] = {
+ { .compatible = "qcom,tcsr", },
+ { },
+};
+
+MODULE_DEVICE_TABLE(of, tcsr_dt_match);
+
+static struct platform_driver tcsr_driver = {
+ .driver = {
+ .name = "tcsr",
+ .owner = THIS_MODULE,
+ .of_match_table = tcsr_dt_match,
+ },
+ .probe = tcsr_probe,
+};
+
+module_platform_driver(tcsr_driver);
+
+MODULE_AUTHOR("Andy Gross <agross@codeaurora.org>");
+MODULE_DESCRIPTION("QCOM TCSR driver");
+MODULE_LICENSE("GPL v2");
--- /dev/null
+++ b/include/dt-bindings/soc/qcom,tcsr.h
@@ -0,0 +1,23 @@
+/* Copyright (c) 2014, The Linux Foundation. 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.
+ */
+#ifndef __DT_BINDINGS_QCOM_TCSR_H
+#define __DT_BINDINGS_QCOM_TCSR_H
+
+#define TCSR_USB_SELECT_USB3_P0 0x1
+#define TCSR_USB_SELECT_USB3_P1 0x2
+#define TCSR_USB_SELECT_USB3_DUAL 0x3
+
+/* TCSR A/B REG */
+#define IPQ806X_TCSR_REG_A_ADM_CRCI_MUX_SEL 0
+#define IPQ806X_TCSR_REG_B_ADM_CRCI_MUX_SEL 1
+
+#endif

View file

@ -0,0 +1,44 @@
--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
@@ -750,6 +750,41 @@
reg = <0x12100000 0x10000>;
};
+ gsbi1: gsbi@12440000 {
+ compatible = "qcom,gsbi-v1.0.0";
+ cell-index = <1>;
+ reg = <0x12440000 0x100>;
+ clocks = <&gcc GSBI1_H_CLK>;
+ clock-names = "iface";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ status = "disabled";
+
+ syscon-tcsr = <&tcsr>;
+
+ gsbi1_serial: serial@12450000 {
+ compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
+ reg = <0x12450000 0x100>,
+ <0x12400000 0x03>;
+ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gcc GSBI1_UART_CLK>, <&gcc GSBI1_H_CLK>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ };
+
+ gsbi1_i2c: i2c@12460000 {
+ compatible = "qcom,i2c-qup-v1.1.1";
+ reg = <0x12460000 0x1000>;
+ interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gcc GSBI1_QUP_CLK>, <&gcc GSBI1_H_CLK>;
+ clock-names = "core", "iface";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+ };
+
gsbi2: gsbi@12480000 {
compatible = "qcom,gsbi-v1.0.0";
cell-index = <2>;

View file

@ -0,0 +1,37 @@
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1793,6 +1793,14 @@ config ARM_ATAG_DTB_COMPAT_CMDLINE_MANGL
endchoice
+config CMDLINE_OVERRIDE
+ bool "Use alternative cmdline from device tree"
+ help
+ Some bootloaders may have uneditable bootargs. While CMDLINE_FORCE can
+ be used, this is not a good option for kernels that are shared across
+ devices. This setting enables using "chosen/cmdline-override" as the
+ cmdline if it exists in the device tree.
+
config CMDLINE
string "Default kernel command string"
default ""
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -1056,6 +1056,17 @@ int __init early_init_dt_scan_chosen(uns
if (p != NULL && l > 0)
strlcpy(data, p, min(l, COMMAND_LINE_SIZE));
+ /* CONFIG_CMDLINE_OVERRIDE is used to fallback to a different
+ * device tree option of chosen/bootargs-override. This is
+ * helpful on boards where u-boot sets bootargs, and is unable
+ * to be modified.
+ */
+#ifdef CONFIG_CMDLINE_OVERRIDE
+ p = of_get_flat_dt_prop(node, "bootargs-override", &l);
+ if (p != NULL && l > 0)
+ strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE));
+#endif
+
/*
* CONFIG_CMDLINE is meant to be a default in case nothing else
* managed to set the command line, unless CONFIG_CMDLINE_FORCE

View file

@ -0,0 +1,12 @@
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -1055,6 +1055,9 @@ int __init early_init_dt_scan_chosen(uns
p = of_get_flat_dt_prop(node, "bootargs", &l);
if (p != NULL && l > 0)
strlcpy(data, p, min(l, COMMAND_LINE_SIZE));
+ p = of_get_flat_dt_prop(node, "bootargs-append", &l);
+ if (p != NULL && l > 0)
+ strlcat(data, p, min_t(int, strlen(data) + (int)l, COMMAND_LINE_SIZE));
/* CONFIG_CMDLINE_OVERRIDE is used to fallback to a different
* device tree option of chosen/bootargs-override. This is

View file

@ -0,0 +1,210 @@
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/leds.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/gpio/consumer.h>
/**
* Driver for the Ubiquiti RGB LED controller (LEDBAR).
* This Controller is based on a Holtek HT32F52241 and connected
* via I2C.
*
* - The Controller needs an enable signal set to high when
* performing a transaction. On the U6-LR, this is located
* at Pin 18 (R6902)
*
* - The Pin is also printed when calling the "usetled" function
* contained in the ubntapp bootloader application.
*/
#define UBNT_LEDBAR_MAX_BRIGHTNESS 0xff
#define UBNT_LEDBAR_TRANSACTION_LENGTH 8
#define UBNT_LEDBAR_TRANSACTION_SUCCESS 0xaa
#define UBNT_LEDBAR_TRANSACTION_BLUE_IDX 2
#define UBNT_LEDBAR_TRANSACTION_GREEN_IDX 3
#define UBNT_LEDBAR_TRANSACTION_RED_IDX 4
struct ubnt_ledbar {
struct mutex lock;
struct i2c_client *client;
struct led_classdev led_red;
struct led_classdev led_green;
struct led_classdev led_blue;
struct gpio_desc *enable_gpio;
};
static int ubnt_ledbar_perform_transaction(struct ubnt_ledbar *ledbar,
char *transaction)
{
int ret;
int i;
for (i = 0; i < UBNT_LEDBAR_TRANSACTION_LENGTH; i++)
i2c_smbus_write_byte(ledbar->client, transaction[i]);
return i2c_smbus_read_byte(ledbar->client);
}
static int ubnt_ledbar_apply_state(struct ubnt_ledbar *ledbar)
{
char setup_msg[UBNT_LEDBAR_TRANSACTION_LENGTH] = {0x40, 0x10, 0x00, 0x00,
0x00, 0x00, 0x00, 0x11};
char led_msg[UBNT_LEDBAR_TRANSACTION_LENGTH] = {0x40, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00};
char i2c_response;
int ret = 0;
mutex_lock(&ledbar->lock);
led_msg[UBNT_LEDBAR_TRANSACTION_BLUE_IDX] = ledbar->led_blue.brightness;
led_msg[UBNT_LEDBAR_TRANSACTION_GREEN_IDX] = ledbar->led_green.brightness;
led_msg[UBNT_LEDBAR_TRANSACTION_RED_IDX] = ledbar->led_red.brightness;
gpiod_set_raw_value(ledbar->enable_gpio, 1);
msleep(10);
i2c_response = ubnt_ledbar_perform_transaction(ledbar, setup_msg);
if (i2c_response != UBNT_LEDBAR_TRANSACTION_SUCCESS) {
dev_err(&ledbar->client->dev, "Error initializing LED transaction: %02x\n", ret);
ret = -EINVAL;
goto out_gpio;
}
i2c_response = ubnt_ledbar_perform_transaction(ledbar, led_msg);
if (i2c_response != UBNT_LEDBAR_TRANSACTION_SUCCESS) {
dev_err(&ledbar->client->dev, "Failed LED transaction: %02x\n", ret);
ret = -EINVAL;
goto out_gpio;
}
msleep(10);
out_gpio:
gpiod_set_raw_value(ledbar->enable_gpio, 0);
mutex_unlock(&ledbar->lock);
return ret;
}
#define UBNT_LEDBAR_CONTROL_RGBS(name) \
static int ubnt_ledbar_set_##name##_brightness(struct led_classdev *led_cdev,\
enum led_brightness value) \
{ \
struct ubnt_ledbar *ledbar = \
container_of(led_cdev, struct ubnt_ledbar, led_##name); \
int ret; \
led_cdev->brightness = value; \
ret = ubnt_ledbar_apply_state(ledbar); \
return ret; \
}
UBNT_LEDBAR_CONTROL_RGBS(red);
UBNT_LEDBAR_CONTROL_RGBS(green);
UBNT_LEDBAR_CONTROL_RGBS(blue);
static int ubnt_ledbar_init_led(struct device_node *np, struct ubnt_ledbar *ledbar,
struct led_classdev *led_cdev)
{
struct led_init_data init_data = {};
int ret;
if (!np)
return 0;
init_data.fwnode = of_fwnode_handle(np);
led_cdev->max_brightness = UBNT_LEDBAR_MAX_BRIGHTNESS;
ret = devm_led_classdev_register_ext(&ledbar->client->dev, led_cdev,
&init_data);
if (ret)
dev_err(&ledbar->client->dev, "led register err: %d\n", ret);
return ret;
}
static int ubnt_ledbar_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct device_node *np = client->dev.of_node;
struct ubnt_ledbar *ledbar;
int ret;
ledbar = devm_kzalloc(&client->dev, sizeof(*ledbar), GFP_KERNEL);
if (!ledbar)
return -ENOMEM;
ledbar->enable_gpio = devm_gpiod_get(&client->dev, "enable", GPIOD_OUT_LOW);
if (IS_ERR(ledbar->enable_gpio)) {
ret = PTR_ERR(ledbar->enable_gpio);
dev_err(&client->dev, "Failed to get enable gpio: %d\n", ret);
return ret;
}
gpiod_direction_output(ledbar->enable_gpio, 0);
ledbar->client = client;
mutex_init(&ledbar->lock);
i2c_set_clientdata(client, ledbar);
ledbar->led_red.brightness_set_blocking = ubnt_ledbar_set_red_brightness;
ubnt_ledbar_init_led(of_get_child_by_name(np, "red"), ledbar, &ledbar->led_red);
ledbar->led_green.brightness_set_blocking = ubnt_ledbar_set_green_brightness;
ubnt_ledbar_init_led(of_get_child_by_name(np, "green"), ledbar, &ledbar->led_green);
ledbar->led_blue.brightness_set_blocking = ubnt_ledbar_set_blue_brightness;
ubnt_ledbar_init_led(of_get_child_by_name(np, "blue"), ledbar, &ledbar->led_blue);
return ubnt_ledbar_apply_state(ledbar);
}
static int ubnt_ledbar_remove(struct i2c_client *client)
{
struct ubnt_ledbar *ledbar = i2c_get_clientdata(client);
mutex_destroy(&ledbar->lock);
return 0;
}
static const struct i2c_device_id ubnt_ledbar_id[] = {
{ "ubnt-ledbar", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ubnt_ledbar_id);
static const struct of_device_id of_ubnt_ledbar_match[] = {
{ .compatible = "ubnt,ledbar", },
{},
};
MODULE_DEVICE_TABLE(of, of_ubnt_ledbar_match);
static struct i2c_driver ubnt_ledbar_driver = {
.driver = {
.name = "ubnt-ledbar",
.of_match_table = of_ubnt_ledbar_match,
},
.probe = ubnt_ledbar_probe,
.remove = ubnt_ledbar_remove,
.id_table = ubnt_ledbar_id,
};
module_i2c_driver(ubnt_ledbar_driver);
MODULE_DESCRIPTION("Ubiquiti LEDBAR driver");
MODULE_AUTHOR("David Bauer <mail@david-bauer.net>");
MODULE_LICENSE("GPL v2");

View file

@ -0,0 +1,13 @@
# SPDX-License-Identifier: GPL-2.0
#
# Copyright (C) 2020 MediaTek Inc. All rights reserved.
# Author: Weijie Gao <weijie.gao@mediatek.com>
#
config MTK_SPI_NAND
tristate "MediaTek SPI NAND flash controller driver"
depends on MTD
default n
help
This option enables access to SPI-NAND flashes through the
MTD interface of MediaTek SPI NAND Flash Controller

View file

@ -0,0 +1,10 @@
# SPDX-License-Identifier: GPL-2.0
#
# Copyright (C) 2020 MediaTek Inc. All rights reserved.
# Author: Weijie Gao <weijie.gao@mediatek.com>
#
obj-y += mtk-snand.o mtk-snand-ecc.o mtk-snand-ids.o mtk-snand-os.o \
mtk-snand-mtd.o
ccflags-y += -DPRIVATE_MTK_SNAND_HEADER

View file

@ -0,0 +1,268 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
*
* Author: Weijie Gao <weijie.gao@mediatek.com>
*/
#ifndef _MTK_SNAND_DEF_H_
#define _MTK_SNAND_DEF_H_
#include "mtk-snand-os.h"
#ifdef PRIVATE_MTK_SNAND_HEADER
#include "mtk-snand.h"
#else
#include <mtk-snand.h>
#endif
struct mtk_snand_plat_dev;
enum snand_flash_io {
SNAND_IO_1_1_1,
SNAND_IO_1_1_2,
SNAND_IO_1_2_2,
SNAND_IO_1_1_4,
SNAND_IO_1_4_4,
__SNAND_IO_MAX
};
#define SPI_IO_1_1_1 BIT(SNAND_IO_1_1_1)
#define SPI_IO_1_1_2 BIT(SNAND_IO_1_1_2)
#define SPI_IO_1_2_2 BIT(SNAND_IO_1_2_2)
#define SPI_IO_1_1_4 BIT(SNAND_IO_1_1_4)
#define SPI_IO_1_4_4 BIT(SNAND_IO_1_4_4)
struct snand_opcode {
uint8_t opcode;
uint8_t dummy;
};
struct snand_io_cap {
uint8_t caps;
struct snand_opcode opcodes[__SNAND_IO_MAX];
};
#define SNAND_OP(_io, _opcode, _dummy) [_io] = { .opcode = (_opcode), \
.dummy = (_dummy) }
#define SNAND_IO_CAP(_name, _caps, ...) \
struct snand_io_cap _name = { .caps = (_caps), \
.opcodes = { __VA_ARGS__ } }
#define SNAND_MAX_ID_LEN 4
enum snand_id_type {
SNAND_ID_DYMMY,
SNAND_ID_ADDR = SNAND_ID_DYMMY,
SNAND_ID_DIRECT,
__SNAND_ID_TYPE_MAX
};
struct snand_id {
uint8_t type; /* enum snand_id_type */
uint8_t len;
uint8_t id[SNAND_MAX_ID_LEN];
};
#define SNAND_ID(_type, ...) \
{ .type = (_type), .id = { __VA_ARGS__ }, \
.len = sizeof((uint8_t[]) { __VA_ARGS__ }) }
struct snand_mem_org {
uint16_t pagesize;
uint16_t sparesize;
uint16_t pages_per_block;
uint16_t blocks_per_die;
uint16_t planes_per_die;
uint16_t ndies;
};
#define SNAND_MEMORG(_ps, _ss, _ppb, _bpd, _ppd, _nd) \
{ .pagesize = (_ps), .sparesize = (_ss), .pages_per_block = (_ppb), \
.blocks_per_die = (_bpd), .planes_per_die = (_ppd), .ndies = (_nd) }
typedef int (*snand_select_die_t)(struct mtk_snand *snf, uint32_t dieidx);
struct snand_flash_info {
const char *model;
struct snand_id id;
const struct snand_mem_org memorg;
const struct snand_io_cap *cap_rd;
const struct snand_io_cap *cap_pl;
snand_select_die_t select_die;
};
#define SNAND_INFO(_model, _id, _memorg, _cap_rd, _cap_pl, ...) \
{ .model = (_model), .id = _id, .memorg = _memorg, \
.cap_rd = (_cap_rd), .cap_pl = (_cap_pl), __VA_ARGS__ }
const struct snand_flash_info *snand_flash_id_lookup(enum snand_id_type type,
const uint8_t *id);
struct mtk_snand_soc_data {
uint16_t sector_size;
uint16_t max_sectors;
uint16_t fdm_size;
uint16_t fdm_ecc_size;
uint16_t fifo_size;
bool bbm_swap;
bool empty_page_check;
uint32_t mastersta_mask;
const uint8_t *spare_sizes;
uint32_t num_spare_size;
};
enum mtk_ecc_regs {
ECC_DECDONE,
};
struct mtk_ecc_soc_data {
const uint8_t *ecc_caps;
uint32_t num_ecc_cap;
const uint32_t *regs;
uint16_t mode_shift;
uint8_t errnum_bits;
uint8_t errnum_shift;
};
struct mtk_snand {
struct mtk_snand_plat_dev *pdev;
void __iomem *nfi_base;
void __iomem *ecc_base;
enum mtk_snand_soc soc;
const struct mtk_snand_soc_data *nfi_soc;
const struct mtk_ecc_soc_data *ecc_soc;
bool snfi_quad_spi;
bool quad_spi_op;
const char *model;
uint64_t size;
uint64_t die_size;
uint32_t erasesize;
uint32_t writesize;
uint32_t oobsize;
uint32_t num_dies;
snand_select_die_t select_die;
uint8_t opcode_rfc;
uint8_t opcode_pl;
uint8_t dummy_rfc;
uint8_t mode_rfc;
uint8_t mode_pl;
uint32_t writesize_mask;
uint32_t writesize_shift;
uint32_t erasesize_mask;
uint32_t erasesize_shift;
uint64_t die_mask;
uint32_t die_shift;
uint32_t spare_per_sector;
uint32_t raw_sector_size;
uint32_t ecc_strength;
uint32_t ecc_steps;
uint32_t ecc_bytes;
uint32_t ecc_parity_bits;
uint8_t *page_cache; /* Used by read/write page */
uint8_t *buf_cache; /* Used by block bad/markbad & auto_oob */
int *sect_bf; /* Used by ECC correction */
};
enum mtk_snand_log_category {
SNAND_LOG_NFI,
SNAND_LOG_SNFI,
SNAND_LOG_ECC,
SNAND_LOG_CHIP,
__SNAND_LOG_CAT_MAX
};
int mtk_ecc_setup(struct mtk_snand *snf, void *fmdaddr, uint32_t max_ecc_bytes,
uint32_t msg_size);
int mtk_snand_ecc_encoder_start(struct mtk_snand *snf);
void mtk_snand_ecc_encoder_stop(struct mtk_snand *snf);
int mtk_snand_ecc_decoder_start(struct mtk_snand *snf);
void mtk_snand_ecc_decoder_stop(struct mtk_snand *snf);
int mtk_ecc_wait_decoder_done(struct mtk_snand *snf);
int mtk_ecc_check_decode_error(struct mtk_snand *snf);
int mtk_ecc_fixup_empty_sector(struct mtk_snand *snf, uint32_t sect);
int mtk_snand_mac_io(struct mtk_snand *snf, const uint8_t *out, uint32_t outlen,
uint8_t *in, uint32_t inlen);
int mtk_snand_set_feature(struct mtk_snand *snf, uint32_t addr, uint32_t val);
int mtk_snand_log(struct mtk_snand_plat_dev *pdev,
enum mtk_snand_log_category cat, const char *fmt, ...);
#define snand_log_nfi(pdev, fmt, ...) \
mtk_snand_log(pdev, SNAND_LOG_NFI, fmt, ##__VA_ARGS__)
#define snand_log_snfi(pdev, fmt, ...) \
mtk_snand_log(pdev, SNAND_LOG_SNFI, fmt, ##__VA_ARGS__)
#define snand_log_ecc(pdev, fmt, ...) \
mtk_snand_log(pdev, SNAND_LOG_ECC, fmt, ##__VA_ARGS__)
#define snand_log_chip(pdev, fmt, ...) \
mtk_snand_log(pdev, SNAND_LOG_CHIP, fmt, ##__VA_ARGS__)
/* ffs64 */
static inline int mtk_snand_ffs64(uint64_t x)
{
if (!x)
return 0;
if (!(x & 0xffffffff))
return ffs((uint32_t)(x >> 32)) + 32;
return ffs((uint32_t)(x & 0xffffffff));
}
/* NFI dummy commands */
#define NFI_CMD_DUMMY_READ 0x00
#define NFI_CMD_DUMMY_WRITE 0x80
/* SPI-NAND opcodes */
#define SNAND_CMD_RESET 0xff
#define SNAND_CMD_BLOCK_ERASE 0xd8
#define SNAND_CMD_READ_FROM_CACHE_QUAD 0xeb
#define SNAND_CMD_WINBOND_SELECT_DIE 0xc2
#define SNAND_CMD_READ_FROM_CACHE_DUAL 0xbb
#define SNAND_CMD_READID 0x9f
#define SNAND_CMD_READ_FROM_CACHE_X4 0x6b
#define SNAND_CMD_READ_FROM_CACHE_X2 0x3b
#define SNAND_CMD_PROGRAM_LOAD_X4 0x32
#define SNAND_CMD_SET_FEATURE 0x1f
#define SNAND_CMD_READ_TO_CACHE 0x13
#define SNAND_CMD_PROGRAM_EXECUTE 0x10
#define SNAND_CMD_GET_FEATURE 0x0f
#define SNAND_CMD_READ_FROM_CACHE 0x0b
#define SNAND_CMD_WRITE_ENABLE 0x06
#define SNAND_CMD_PROGRAM_LOAD 0x02
/* SPI-NAND feature addresses */
#define SNAND_FEATURE_MICRON_DIE_ADDR 0xd0
#define SNAND_MICRON_DIE_SEL_1 BIT(6)
#define SNAND_FEATURE_STATUS_ADDR 0xc0
#define SNAND_STATUS_OIP BIT(0)
#define SNAND_STATUS_WEL BIT(1)
#define SNAND_STATUS_ERASE_FAIL BIT(2)
#define SNAND_STATUS_PROGRAM_FAIL BIT(3)
#define SNAND_FEATURE_CONFIG_ADDR 0xb0
#define SNAND_FEATURE_QUAD_ENABLE BIT(0)
#define SNAND_FEATURE_ECC_EN BIT(4)
#define SNAND_FEATURE_PROTECT_ADDR 0xa0
#endif /* _MTK_SNAND_DEF_H_ */

View file

@ -0,0 +1,379 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
*
* Author: Weijie Gao <weijie.gao@mediatek.com>
*/
#include "mtk-snand-def.h"
/* ECC registers */
#define ECC_ENCCON 0x000
#define ENC_EN BIT(0)
#define ECC_ENCCNFG 0x004
#define ENC_MS_S 16
#define ENC_BURST_EN BIT(8)
#define ENC_TNUM_S 0
#define ECC_ENCIDLE 0x00c
#define ENC_IDLE BIT(0)
#define ECC_DECCON 0x100
#define DEC_EN BIT(0)
#define ECC_DECCNFG 0x104
#define DEC_EMPTY_EN BIT(31)
#define DEC_CS_S 16
#define DEC_CON_S 12
#define DEC_CON_CORRECT 3
#define DEC_BURST_EN BIT(8)
#define DEC_TNUM_S 0
#define ECC_DECIDLE 0x10c
#define DEC_IDLE BIT(0)
#define ECC_DECENUM0 0x114
#define ECC_DECENUM(n) (ECC_DECENUM0 + (n) * 4)
/* ECC_ENCIDLE & ECC_DECIDLE */
#define ECC_IDLE BIT(0)
/* ENC_MODE & DEC_MODE */
#define ECC_MODE_NFI 1
#define ECC_TIMEOUT 500000
static const uint8_t mt7622_ecc_caps[] = { 4, 6, 8, 10, 12 };
static const uint32_t mt7622_ecc_regs[] = {
[ECC_DECDONE] = 0x11c,
};
static const struct mtk_ecc_soc_data mtk_ecc_socs[__SNAND_SOC_MAX] = {
[SNAND_SOC_MT7622] = {
.ecc_caps = mt7622_ecc_caps,
.num_ecc_cap = ARRAY_SIZE(mt7622_ecc_caps),
.regs = mt7622_ecc_regs,
.mode_shift = 4,
.errnum_bits = 5,
.errnum_shift = 5,
},
[SNAND_SOC_MT7629] = {
.ecc_caps = mt7622_ecc_caps,
.num_ecc_cap = ARRAY_SIZE(mt7622_ecc_caps),
.regs = mt7622_ecc_regs,
.mode_shift = 4,
.errnum_bits = 5,
.errnum_shift = 5,
},
};
static inline uint32_t ecc_read32(struct mtk_snand *snf, uint32_t reg)
{
return readl(snf->ecc_base + reg);
}
static inline void ecc_write32(struct mtk_snand *snf, uint32_t reg,
uint32_t val)
{
writel(val, snf->ecc_base + reg);
}
static inline void ecc_write16(struct mtk_snand *snf, uint32_t reg,
uint16_t val)
{
writew(val, snf->ecc_base + reg);
}
static int mtk_ecc_poll(struct mtk_snand *snf, uint32_t reg, uint32_t bits)
{
uint32_t val;
return read16_poll_timeout(snf->ecc_base + reg, val, (val & bits), 0,
ECC_TIMEOUT);
}
static int mtk_ecc_wait_idle(struct mtk_snand *snf, uint32_t reg)
{
int ret;
ret = mtk_ecc_poll(snf, reg, ECC_IDLE);
if (ret) {
snand_log_ecc(snf->pdev, "ECC engine is busy\n");
return -EBUSY;
}
return 0;
}
int mtk_ecc_setup(struct mtk_snand *snf, void *fmdaddr, uint32_t max_ecc_bytes,
uint32_t msg_size)
{
uint32_t i, val, ecc_msg_bits, ecc_strength;
int ret;
snf->ecc_soc = &mtk_ecc_socs[snf->soc];
snf->ecc_parity_bits = fls(1 + 8 * msg_size);
ecc_strength = max_ecc_bytes * 8 / snf->ecc_parity_bits;
for (i = snf->ecc_soc->num_ecc_cap - 1; i >= 0; i--) {
if (snf->ecc_soc->ecc_caps[i] <= ecc_strength)
break;
}
if (unlikely(i < 0)) {
snand_log_ecc(snf->pdev, "Page size %u+%u is not supported\n",
snf->writesize, snf->oobsize);
return -ENOTSUPP;
}
snf->ecc_strength = snf->ecc_soc->ecc_caps[i];
snf->ecc_bytes = DIV_ROUND_UP(snf->ecc_strength * snf->ecc_parity_bits,
8);
/* Encoder config */
ecc_write16(snf, ECC_ENCCON, 0);
ret = mtk_ecc_wait_idle(snf, ECC_ENCIDLE);
if (ret)
return ret;
ecc_msg_bits = msg_size * 8;
val = (ecc_msg_bits << ENC_MS_S) |
(ECC_MODE_NFI << snf->ecc_soc->mode_shift) | i;
ecc_write32(snf, ECC_ENCCNFG, val);
/* Decoder config */
ecc_write16(snf, ECC_DECCON, 0);
ret = mtk_ecc_wait_idle(snf, ECC_DECIDLE);
if (ret)
return ret;
ecc_msg_bits += snf->ecc_strength * snf->ecc_parity_bits;
val = DEC_EMPTY_EN | (ecc_msg_bits << DEC_CS_S) |
(DEC_CON_CORRECT << DEC_CON_S) |
(ECC_MODE_NFI << snf->ecc_soc->mode_shift) | i;
ecc_write32(snf, ECC_DECCNFG, val);
return 0;
}
int mtk_snand_ecc_encoder_start(struct mtk_snand *snf)
{
int ret;
ret = mtk_ecc_wait_idle(snf, ECC_ENCIDLE);
if (ret) {
ecc_write16(snf, ECC_ENCCON, 0);
mtk_ecc_wait_idle(snf, ECC_ENCIDLE);
}
ecc_write16(snf, ECC_ENCCON, ENC_EN);
return 0;
}
void mtk_snand_ecc_encoder_stop(struct mtk_snand *snf)
{
mtk_ecc_wait_idle(snf, ECC_ENCIDLE);
ecc_write16(snf, ECC_ENCCON, 0);
}
int mtk_snand_ecc_decoder_start(struct mtk_snand *snf)
{
int ret;
ret = mtk_ecc_wait_idle(snf, ECC_DECIDLE);
if (ret) {
ecc_write16(snf, ECC_DECCON, 0);
mtk_ecc_wait_idle(snf, ECC_DECIDLE);
}
ecc_write16(snf, ECC_DECCON, DEC_EN);
return 0;
}
void mtk_snand_ecc_decoder_stop(struct mtk_snand *snf)
{
mtk_ecc_wait_idle(snf, ECC_DECIDLE);
ecc_write16(snf, ECC_DECCON, 0);
}
int mtk_ecc_wait_decoder_done(struct mtk_snand *snf)
{
uint16_t val, step_mask = (1 << snf->ecc_steps) - 1;
uint32_t reg = snf->ecc_soc->regs[ECC_DECDONE];
int ret;
ret = read16_poll_timeout(snf->ecc_base + reg, val,
(val & step_mask) == step_mask, 0,
ECC_TIMEOUT);
if (ret)
snand_log_ecc(snf->pdev, "ECC decoder is busy\n");
return ret;
}
int mtk_ecc_check_decode_error(struct mtk_snand *snf)
{
uint32_t i, regi, fi, errnum;
uint32_t errnum_shift = snf->ecc_soc->errnum_shift;
uint32_t errnum_mask = (1 << snf->ecc_soc->errnum_bits) - 1;
int ret = 0;
for (i = 0; i < snf->ecc_steps; i++) {
regi = i / 4;
fi = i % 4;
errnum = ecc_read32(snf, ECC_DECENUM(regi));
errnum = (errnum >> (fi * errnum_shift)) & errnum_mask;
if (errnum <= snf->ecc_strength) {
snf->sect_bf[i] = errnum;
} else {
snf->sect_bf[i] = -1;
ret = -EBADMSG;
}
}
return ret;
}
static int mtk_ecc_check_buf_bitflips(struct mtk_snand *snf, const void *buf,
size_t len, uint32_t bitflips)
{
const uint8_t *buf8 = buf;
const uint32_t *buf32;
uint32_t d, weight;
while (len && ((uintptr_t)buf8) % sizeof(uint32_t)) {
weight = hweight8(*buf8);
bitflips += BITS_PER_BYTE - weight;
buf8++;
len--;
if (bitflips > snf->ecc_strength)
return -EBADMSG;
}
buf32 = (const uint32_t *)buf8;
while (len >= sizeof(uint32_t)) {
d = *buf32;
if (d != ~0) {
weight = hweight32(d);
bitflips += sizeof(uint32_t) * BITS_PER_BYTE - weight;
}
buf32++;
len -= sizeof(uint32_t);
if (bitflips > snf->ecc_strength)
return -EBADMSG;
}
buf8 = (const uint8_t *)buf32;
while (len) {
weight = hweight8(*buf8);
bitflips += BITS_PER_BYTE - weight;
buf8++;
len--;
if (bitflips > snf->ecc_strength)
return -EBADMSG;
}
return bitflips;
}
static int mtk_ecc_check_parity_bitflips(struct mtk_snand *snf, const void *buf,
uint32_t bits, uint32_t bitflips)
{
uint32_t len, i;
uint8_t b;
int rc;
len = bits >> 3;
bits &= 7;
rc = mtk_ecc_check_buf_bitflips(snf, buf, len, bitflips);
if (!bits || rc < 0)
return rc;
bitflips = rc;
/* We want a precise count of bits */
b = ((const uint8_t *)buf)[len];
for (i = 0; i < bits; i++) {
if (!(b & BIT(i)))
bitflips++;
}
if (bitflips > snf->ecc_strength)
return -EBADMSG;
return bitflips;
}
static void mtk_ecc_reset_parity(void *buf, uint32_t bits)
{
uint32_t len;
len = bits >> 3;
bits &= 7;
memset(buf, 0xff, len);
/* Only reset bits protected by ECC to 1 */
if (bits)
((uint8_t *)buf)[len] |= GENMASK(bits - 1, 0);
}
int mtk_ecc_fixup_empty_sector(struct mtk_snand *snf, uint32_t sect)
{
uint32_t ecc_bytes = snf->spare_per_sector - snf->nfi_soc->fdm_size;
uint8_t *oob = snf->page_cache + snf->writesize;
uint8_t *data_ptr, *fdm_ptr, *ecc_ptr;
int bitflips = 0, ecc_bits, parity_bits;
parity_bits = fls(snf->nfi_soc->sector_size * 8);
ecc_bits = snf->ecc_strength * parity_bits;
data_ptr = snf->page_cache + sect * snf->nfi_soc->sector_size;
fdm_ptr = oob + sect * snf->nfi_soc->fdm_size;
ecc_ptr = oob + snf->ecc_steps * snf->nfi_soc->fdm_size +
sect * ecc_bytes;
/*
* Check whether DATA + FDM + ECC of a sector contains correctable
* bitflips
*/
bitflips = mtk_ecc_check_buf_bitflips(snf, data_ptr,
snf->nfi_soc->sector_size,
bitflips);
if (bitflips < 0)
return -EBADMSG;
bitflips = mtk_ecc_check_buf_bitflips(snf, fdm_ptr,
snf->nfi_soc->fdm_ecc_size,
bitflips);
if (bitflips < 0)
return -EBADMSG;
bitflips = mtk_ecc_check_parity_bitflips(snf, ecc_ptr, ecc_bits,
bitflips);
if (bitflips < 0)
return -EBADMSG;
if (!bitflips)
return 0;
/* Reset the data of this sector to 0xff */
memset(data_ptr, 0xff, snf->nfi_soc->sector_size);
memset(fdm_ptr, 0xff, snf->nfi_soc->fdm_ecc_size);
mtk_ecc_reset_parity(ecc_ptr, ecc_bits);
return bitflips;
}

View file

@ -0,0 +1,511 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
*
* Author: Weijie Gao <weijie.gao@mediatek.com>
*/
#include "mtk-snand-def.h"
static int mtk_snand_winbond_select_die(struct mtk_snand *snf, uint32_t dieidx);
static int mtk_snand_micron_select_die(struct mtk_snand *snf, uint32_t dieidx);
#define SNAND_MEMORG_512M_2K_64 SNAND_MEMORG(2048, 64, 64, 512, 1, 1)
#define SNAND_MEMORG_1G_2K_64 SNAND_MEMORG(2048, 64, 64, 1024, 1, 1)
#define SNAND_MEMORG_2G_2K_64 SNAND_MEMORG(2048, 64, 64, 2048, 1, 1)
#define SNAND_MEMORG_2G_2K_120 SNAND_MEMORG(2048, 120, 64, 2048, 1, 1)
#define SNAND_MEMORG_4G_2K_64 SNAND_MEMORG(2048, 64, 64, 4096, 1, 1)
#define SNAND_MEMORG_1G_2K_120 SNAND_MEMORG(2048, 120, 64, 1024, 1, 1)
#define SNAND_MEMORG_1G_2K_128 SNAND_MEMORG(2048, 128, 64, 1024, 1, 1)
#define SNAND_MEMORG_2G_2K_128 SNAND_MEMORG(2048, 128, 64, 2048, 1, 1)
#define SNAND_MEMORG_4G_2K_128 SNAND_MEMORG(2048, 128, 64, 4096, 1, 1)
#define SNAND_MEMORG_4G_4K_240 SNAND_MEMORG(4096, 240, 64, 2048, 1, 1)
#define SNAND_MEMORG_4G_4K_256 SNAND_MEMORG(4096, 256, 64, 2048, 1, 1)
#define SNAND_MEMORG_8G_4K_256 SNAND_MEMORG(4096, 256, 64, 4096, 1, 1)
#define SNAND_MEMORG_2G_2K_64_2P SNAND_MEMORG(2048, 64, 64, 2048, 2, 1)
#define SNAND_MEMORG_2G_2K_64_2D SNAND_MEMORG(2048, 64, 64, 1024, 1, 2)
#define SNAND_MEMORG_2G_2K_128_2P SNAND_MEMORG(2048, 128, 64, 2048, 2, 1)
#define SNAND_MEMORG_4G_2K_64_2P SNAND_MEMORG(2048, 64, 64, 4096, 2, 1)
#define SNAND_MEMORG_4G_2K_128_2P_2D SNAND_MEMORG(2048, 128, 64, 2048, 2, 2)
#define SNAND_MEMORG_8G_4K_256_2D SNAND_MEMORG(4096, 256, 64, 2048, 1, 2)
static const SNAND_IO_CAP(snand_cap_read_from_cache_quad,
SPI_IO_1_1_1 | SPI_IO_1_1_2 | SPI_IO_1_2_2 | SPI_IO_1_1_4 |
SPI_IO_1_4_4,
SNAND_OP(SNAND_IO_1_1_1, SNAND_CMD_READ_FROM_CACHE, 8),
SNAND_OP(SNAND_IO_1_1_2, SNAND_CMD_READ_FROM_CACHE_X2, 8),
SNAND_OP(SNAND_IO_1_2_2, SNAND_CMD_READ_FROM_CACHE_DUAL, 4),
SNAND_OP(SNAND_IO_1_1_4, SNAND_CMD_READ_FROM_CACHE_X4, 8),
SNAND_OP(SNAND_IO_1_4_4, SNAND_CMD_READ_FROM_CACHE_QUAD, 4));
static const SNAND_IO_CAP(snand_cap_read_from_cache_quad_q2d,
SPI_IO_1_1_1 | SPI_IO_1_1_2 | SPI_IO_1_2_2 | SPI_IO_1_1_4 |
SPI_IO_1_4_4,
SNAND_OP(SNAND_IO_1_1_1, SNAND_CMD_READ_FROM_CACHE, 8),
SNAND_OP(SNAND_IO_1_1_2, SNAND_CMD_READ_FROM_CACHE_X2, 8),
SNAND_OP(SNAND_IO_1_2_2, SNAND_CMD_READ_FROM_CACHE_DUAL, 4),
SNAND_OP(SNAND_IO_1_1_4, SNAND_CMD_READ_FROM_CACHE_X4, 8),
SNAND_OP(SNAND_IO_1_4_4, SNAND_CMD_READ_FROM_CACHE_QUAD, 2));
static const SNAND_IO_CAP(snand_cap_read_from_cache_quad_a8d,
SPI_IO_1_1_1 | SPI_IO_1_1_2 | SPI_IO_1_2_2 | SPI_IO_1_1_4 |
SPI_IO_1_4_4,
SNAND_OP(SNAND_IO_1_1_1, SNAND_CMD_READ_FROM_CACHE, 8),
SNAND_OP(SNAND_IO_1_1_2, SNAND_CMD_READ_FROM_CACHE_X2, 8),
SNAND_OP(SNAND_IO_1_2_2, SNAND_CMD_READ_FROM_CACHE_DUAL, 8),
SNAND_OP(SNAND_IO_1_1_4, SNAND_CMD_READ_FROM_CACHE_X4, 8),
SNAND_OP(SNAND_IO_1_4_4, SNAND_CMD_READ_FROM_CACHE_QUAD, 8));
static const SNAND_IO_CAP(snand_cap_read_from_cache_x4,
SPI_IO_1_1_1 | SPI_IO_1_1_2 | SPI_IO_1_1_4,
SNAND_OP(SNAND_IO_1_1_1, SNAND_CMD_READ_FROM_CACHE, 8),
SNAND_OP(SNAND_IO_1_1_2, SNAND_CMD_READ_FROM_CACHE_X2, 8),
SNAND_OP(SNAND_IO_1_1_4, SNAND_CMD_READ_FROM_CACHE_X4, 8));
static const SNAND_IO_CAP(snand_cap_read_from_cache_x4_only,
SPI_IO_1_1_1 | SPI_IO_1_1_4,
SNAND_OP(SNAND_IO_1_1_1, SNAND_CMD_READ_FROM_CACHE, 8),
SNAND_OP(SNAND_IO_1_1_4, SNAND_CMD_READ_FROM_CACHE_X4, 8));
static const SNAND_IO_CAP(snand_cap_program_load_x1,
SPI_IO_1_1_1,
SNAND_OP(SNAND_IO_1_1_1, SNAND_CMD_PROGRAM_LOAD, 0));
static const SNAND_IO_CAP(snand_cap_program_load_x4,
SPI_IO_1_1_1 | SPI_IO_1_1_4,
SNAND_OP(SNAND_IO_1_1_1, SNAND_CMD_PROGRAM_LOAD, 0),
SNAND_OP(SNAND_IO_1_1_4, SNAND_CMD_PROGRAM_LOAD_X4, 0));
static const struct snand_flash_info snand_flash_ids[] = {
SNAND_INFO("W25N512GV", SNAND_ID(SNAND_ID_DYMMY, 0xef, 0xaa, 0x20),
SNAND_MEMORG_512M_2K_64,
&snand_cap_read_from_cache_quad,
&snand_cap_program_load_x4),
SNAND_INFO("W25N01GV", SNAND_ID(SNAND_ID_DYMMY, 0xef, 0xaa, 0x21),
SNAND_MEMORG_1G_2K_64,
&snand_cap_read_from_cache_quad,
&snand_cap_program_load_x4),
SNAND_INFO("W25M02GV", SNAND_ID(SNAND_ID_DYMMY, 0xef, 0xab, 0x21),
SNAND_MEMORG_2G_2K_64_2D,
&snand_cap_read_from_cache_quad,
&snand_cap_program_load_x4,
mtk_snand_winbond_select_die),
SNAND_INFO("W25N02KV", SNAND_ID(SNAND_ID_DYMMY, 0xef, 0xaa, 0x22),
SNAND_MEMORG_2G_2K_128,
&snand_cap_read_from_cache_quad,
&snand_cap_program_load_x4),
SNAND_INFO("GD5F1GQ4UAWxx", SNAND_ID(SNAND_ID_ADDR, 0xc8, 0x10),
SNAND_MEMORG_1G_2K_64,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("GD5F1GQ4UExIG", SNAND_ID(SNAND_ID_ADDR, 0xc8, 0xd1),
SNAND_MEMORG_1G_2K_128,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("GD5F1GQ4UExxH", SNAND_ID(SNAND_ID_ADDR, 0xc8, 0xd9),
SNAND_MEMORG_1G_2K_64,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("GD5F1GQ4xAYIG", SNAND_ID(SNAND_ID_ADDR, 0xc8, 0xf1),
SNAND_MEMORG_1G_2K_64,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("GD5F2GQ4UExIG", SNAND_ID(SNAND_ID_ADDR, 0xc8, 0xd2),
SNAND_MEMORG_2G_2K_128,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("GD5F2GQ5UExxH", SNAND_ID(SNAND_ID_ADDR, 0xc8, 0x32),
SNAND_MEMORG_2G_2K_64,
&snand_cap_read_from_cache_quad_a8d,
&snand_cap_program_load_x4),
SNAND_INFO("GD5F2GQ4xAYIG", SNAND_ID(SNAND_ID_ADDR, 0xc8, 0xf2),
SNAND_MEMORG_2G_2K_64,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("GD5F4GQ4UBxIG", SNAND_ID(SNAND_ID_ADDR, 0xc8, 0xd4),
SNAND_MEMORG_4G_4K_256,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("GD5F4GQ4xAYIG", SNAND_ID(SNAND_ID_ADDR, 0xc8, 0xf4),
SNAND_MEMORG_4G_2K_64,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("GD5F2GQ5UExxG", SNAND_ID(SNAND_ID_DYMMY, 0xc8, 0x52),
SNAND_MEMORG_2G_2K_128,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("GD5F4GQ4UCxIG", SNAND_ID(SNAND_ID_DYMMY, 0xc8, 0xb4),
SNAND_MEMORG_4G_4K_256,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("MX35LF1GE4AB", SNAND_ID(SNAND_ID_DYMMY, 0xc2, 0x12),
SNAND_MEMORG_1G_2K_64,
&snand_cap_read_from_cache_x4,
&snand_cap_program_load_x4),
SNAND_INFO("MX35LF1G24AD", SNAND_ID(SNAND_ID_DYMMY, 0xc2, 0x14),
SNAND_MEMORG_1G_2K_128,
&snand_cap_read_from_cache_quad,
&snand_cap_program_load_x4),
SNAND_INFO("MX31LF1GE4BC", SNAND_ID(SNAND_ID_DYMMY, 0xc2, 0x1e),
SNAND_MEMORG_1G_2K_64,
&snand_cap_read_from_cache_x4,
&snand_cap_program_load_x4),
SNAND_INFO("MX35LF2GE4AB", SNAND_ID(SNAND_ID_DYMMY, 0xc2, 0x22),
SNAND_MEMORG_2G_2K_64,
&snand_cap_read_from_cache_x4,
&snand_cap_program_load_x4),
SNAND_INFO("MX35LF2G24AD", SNAND_ID(SNAND_ID_DYMMY, 0xc2, 0x24),
SNAND_MEMORG_2G_2K_128,
&snand_cap_read_from_cache_quad,
&snand_cap_program_load_x4),
SNAND_INFO("MX35LF2GE4AD", SNAND_ID(SNAND_ID_DYMMY, 0xc2, 0x26),
SNAND_MEMORG_2G_2K_128,
&snand_cap_read_from_cache_x4,
&snand_cap_program_load_x4),
SNAND_INFO("MX35LF2G14AC", SNAND_ID(SNAND_ID_DYMMY, 0xc2, 0x20),
SNAND_MEMORG_2G_2K_64,
&snand_cap_read_from_cache_x4,
&snand_cap_program_load_x4),
SNAND_INFO("MX35LF4G24AD", SNAND_ID(SNAND_ID_DYMMY, 0xc2, 0x35),
SNAND_MEMORG_4G_4K_256,
&snand_cap_read_from_cache_quad,
&snand_cap_program_load_x4),
SNAND_INFO("MX35LF4GE4AD", SNAND_ID(SNAND_ID_DYMMY, 0xc2, 0x37),
SNAND_MEMORG_4G_4K_256,
&snand_cap_read_from_cache_x4,
&snand_cap_program_load_x4),
SNAND_INFO("MT29F1G01AAADD", SNAND_ID(SNAND_ID_DYMMY, 0x2c, 0x12),
SNAND_MEMORG_1G_2K_64,
&snand_cap_read_from_cache_x4,
&snand_cap_program_load_x1),
SNAND_INFO("MT29F1G01ABAFD", SNAND_ID(SNAND_ID_DYMMY, 0x2c, 0x14),
SNAND_MEMORG_1G_2K_128,
&snand_cap_read_from_cache_quad,
&snand_cap_program_load_x4),
SNAND_INFO("MT29F2G01AAAED", SNAND_ID(SNAND_ID_DYMMY, 0x2c, 0x9f),
SNAND_MEMORG_2G_2K_64_2P,
&snand_cap_read_from_cache_x4,
&snand_cap_program_load_x1),
SNAND_INFO("MT29F2G01ABAGD", SNAND_ID(SNAND_ID_DYMMY, 0x2c, 0x24),
SNAND_MEMORG_2G_2K_128_2P,
&snand_cap_read_from_cache_quad,
&snand_cap_program_load_x4),
SNAND_INFO("MT29F4G01AAADD", SNAND_ID(SNAND_ID_DYMMY, 0x2c, 0x32),
SNAND_MEMORG_4G_2K_64_2P,
&snand_cap_read_from_cache_x4,
&snand_cap_program_load_x1),
SNAND_INFO("MT29F4G01ABAFD", SNAND_ID(SNAND_ID_DYMMY, 0x2c, 0x34),
SNAND_MEMORG_4G_4K_256,
&snand_cap_read_from_cache_quad,
&snand_cap_program_load_x4),
SNAND_INFO("MT29F4G01ADAGD", SNAND_ID(SNAND_ID_DYMMY, 0x2c, 0x36),
SNAND_MEMORG_4G_2K_128_2P_2D,
&snand_cap_read_from_cache_quad,
&snand_cap_program_load_x4,
mtk_snand_micron_select_die),
SNAND_INFO("MT29F8G01ADAFD", SNAND_ID(SNAND_ID_DYMMY, 0x2c, 0x46),
SNAND_MEMORG_8G_4K_256_2D,
&snand_cap_read_from_cache_quad,
&snand_cap_program_load_x4,
mtk_snand_micron_select_die),
SNAND_INFO("TC58CVG0S3HRAIG", SNAND_ID(SNAND_ID_DYMMY, 0x98, 0xc2),
SNAND_MEMORG_1G_2K_128,
&snand_cap_read_from_cache_x4,
&snand_cap_program_load_x1),
SNAND_INFO("TC58CVG1S3HRAIG", SNAND_ID(SNAND_ID_DYMMY, 0x98, 0xcb),
SNAND_MEMORG_2G_2K_128,
&snand_cap_read_from_cache_x4,
&snand_cap_program_load_x1),
SNAND_INFO("TC58CVG2S0HRAIG", SNAND_ID(SNAND_ID_DYMMY, 0x98, 0xcd),
SNAND_MEMORG_4G_4K_256,
&snand_cap_read_from_cache_x4,
&snand_cap_program_load_x1),
SNAND_INFO("TC58CVG0S3HRAIJ", SNAND_ID(SNAND_ID_DYMMY, 0x98, 0xe2),
SNAND_MEMORG_1G_2K_128,
&snand_cap_read_from_cache_x4,
&snand_cap_program_load_x4),
SNAND_INFO("TC58CVG1S3HRAIJ", SNAND_ID(SNAND_ID_DYMMY, 0x98, 0xeb),
SNAND_MEMORG_2G_2K_128,
&snand_cap_read_from_cache_x4,
&snand_cap_program_load_x4),
SNAND_INFO("TC58CVG2S0HRAIJ", SNAND_ID(SNAND_ID_DYMMY, 0x98, 0xed),
SNAND_MEMORG_4G_4K_256,
&snand_cap_read_from_cache_x4,
&snand_cap_program_load_x4),
SNAND_INFO("TH58CVG3S0HRAIJ", SNAND_ID(SNAND_ID_DYMMY, 0x98, 0xe4),
SNAND_MEMORG_8G_4K_256,
&snand_cap_read_from_cache_x4,
&snand_cap_program_load_x4),
SNAND_INFO("F50L512M41A", SNAND_ID(SNAND_ID_DYMMY, 0xc8, 0x20),
SNAND_MEMORG_512M_2K_64,
&snand_cap_read_from_cache_x4,
&snand_cap_program_load_x4),
SNAND_INFO("F50L1G41A", SNAND_ID(SNAND_ID_DYMMY, 0xc8, 0x21),
SNAND_MEMORG_1G_2K_64,
&snand_cap_read_from_cache_x4,
&snand_cap_program_load_x4),
SNAND_INFO("F50L1G41LB", SNAND_ID(SNAND_ID_DYMMY, 0xc8, 0x01),
SNAND_MEMORG_1G_2K_64,
&snand_cap_read_from_cache_quad,
&snand_cap_program_load_x4),
SNAND_INFO("F50L2G41LB", SNAND_ID(SNAND_ID_DYMMY, 0xc8, 0x0a),
SNAND_MEMORG_2G_2K_64_2D,
&snand_cap_read_from_cache_quad,
&snand_cap_program_load_x4,
mtk_snand_winbond_select_die),
SNAND_INFO("CS11G0T0A0AA", SNAND_ID(SNAND_ID_DYMMY, 0x6b, 0x00),
SNAND_MEMORG_1G_2K_128,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("CS11G0G0A0AA", SNAND_ID(SNAND_ID_DYMMY, 0x6b, 0x10),
SNAND_MEMORG_1G_2K_128,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("CS11G0S0A0AA", SNAND_ID(SNAND_ID_DYMMY, 0x6b, 0x20),
SNAND_MEMORG_1G_2K_64,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("CS11G1T0A0AA", SNAND_ID(SNAND_ID_DYMMY, 0x6b, 0x01),
SNAND_MEMORG_2G_2K_128,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("CS11G1S0A0AA", SNAND_ID(SNAND_ID_DYMMY, 0x6b, 0x21),
SNAND_MEMORG_2G_2K_64,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("CS11G2T0A0AA", SNAND_ID(SNAND_ID_DYMMY, 0x6b, 0x02),
SNAND_MEMORG_4G_2K_128,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("CS11G2S0A0AA", SNAND_ID(SNAND_ID_DYMMY, 0x6b, 0x22),
SNAND_MEMORG_4G_2K_64,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73B044VCA", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x01),
SNAND_MEMORG_512M_2K_64,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73C044SNB", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x11),
SNAND_MEMORG_1G_2K_120,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73C044SNF", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x09),
SNAND_MEMORG_1G_2K_128,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73C044VCA", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x18),
SNAND_MEMORG_1G_2K_64,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73C044SNA", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x19),
SNAND_MEMORG(2048, 64, 128, 512, 1, 1),
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73C044VCD", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x1c),
SNAND_MEMORG_1G_2K_64,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73C044SND", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x1d),
SNAND_MEMORG_1G_2K_64,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73D044SND", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x1e),
SNAND_MEMORG_2G_2K_64,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73C044VCC", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x22),
SNAND_MEMORG_1G_2K_64,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73C044VCF", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x25),
SNAND_MEMORG_1G_2K_64,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73C044SNC", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x31),
SNAND_MEMORG_1G_2K_128,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73D044SNC", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x0a),
SNAND_MEMORG_2G_2K_120,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73D044SNA", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x12),
SNAND_MEMORG_2G_2K_128,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73D044SNF", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x10),
SNAND_MEMORG_2G_2K_128,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73D044VCA", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x13),
SNAND_MEMORG_2G_2K_128,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73D044VCB", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x14),
SNAND_MEMORG_2G_2K_64,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73D044VCD", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x17),
SNAND_MEMORG_2G_2K_128,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73D044VCH", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x1b),
SNAND_MEMORG_2G_2K_64,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73D044SND", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x1d),
SNAND_MEMORG_2G_2K_64,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73D044VCG", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x1f),
SNAND_MEMORG_2G_2K_64,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73D044VCE", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x20),
SNAND_MEMORG_2G_2K_64,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73D044VCL", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x2e),
SNAND_MEMORG_2G_2K_128,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73D044SNB", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x32),
SNAND_MEMORG_2G_2K_128,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73E044SNA", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x03),
SNAND_MEMORG_4G_4K_256,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73E044SND", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x0b),
SNAND_MEMORG_4G_4K_240,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73E044SNB", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x23),
SNAND_MEMORG_4G_4K_256,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73E044VCA", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x2c),
SNAND_MEMORG_4G_4K_256,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73E044VCB", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x2f),
SNAND_MEMORG_4G_2K_128,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73F044SNA", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x24),
SNAND_MEMORG_8G_4K_256,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73F044VCA", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x2d),
SNAND_MEMORG_8G_4K_256,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73E044SNE", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x0e),
SNAND_MEMORG_8G_4K_256,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73C044SNG", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x0c),
SNAND_MEMORG_1G_2K_120,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("EM73D044VCN", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x0f),
SNAND_MEMORG_2G_2K_64,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("FM35Q1GA", SNAND_ID(SNAND_ID_DYMMY, 0xe5, 0x71),
SNAND_MEMORG_1G_2K_64,
&snand_cap_read_from_cache_x4,
&snand_cap_program_load_x4),
SNAND_INFO("PN26G01A", SNAND_ID(SNAND_ID_DYMMY, 0xa1, 0xe1),
SNAND_MEMORG_1G_2K_128,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("PN26G02A", SNAND_ID(SNAND_ID_DYMMY, 0xa1, 0xe2),
SNAND_MEMORG_2G_2K_128,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("IS37SML01G1", SNAND_ID(SNAND_ID_DYMMY, 0xc8, 0x21),
SNAND_MEMORG_1G_2K_64,
&snand_cap_read_from_cache_x4,
&snand_cap_program_load_x4),
SNAND_INFO("ATO25D1GA", SNAND_ID(SNAND_ID_DYMMY, 0x9b, 0x12),
SNAND_MEMORG_1G_2K_64,
&snand_cap_read_from_cache_x4_only,
&snand_cap_program_load_x4),
SNAND_INFO("HYF1GQ4U", SNAND_ID(SNAND_ID_DYMMY, 0xc9, 0x51),
SNAND_MEMORG_1G_2K_128,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
SNAND_INFO("HYF2GQ4U", SNAND_ID(SNAND_ID_DYMMY, 0xc9, 0x52),
SNAND_MEMORG_2G_2K_128,
&snand_cap_read_from_cache_quad_q2d,
&snand_cap_program_load_x4),
};
static int mtk_snand_winbond_select_die(struct mtk_snand *snf, uint32_t dieidx)
{
uint8_t op[2];
if (dieidx > 1) {
snand_log_chip(snf->pdev, "Invalid die index %u\n", dieidx);
return -EINVAL;
}
op[0] = SNAND_CMD_WINBOND_SELECT_DIE;
op[1] = (uint8_t)dieidx;
return mtk_snand_mac_io(snf, op, sizeof(op), NULL, 0);
}
static int mtk_snand_micron_select_die(struct mtk_snand *snf, uint32_t dieidx)
{
int ret;
if (dieidx > 1) {
snand_log_chip(snf->pdev, "Invalid die index %u\n", dieidx);
return -EINVAL;
}
ret = mtk_snand_set_feature(snf, SNAND_FEATURE_MICRON_DIE_ADDR,
SNAND_MICRON_DIE_SEL_1);
if (ret) {
snand_log_chip(snf->pdev,
"Failed to set die selection feature\n");
return ret;
}
return 0;
}
const struct snand_flash_info *snand_flash_id_lookup(enum snand_id_type type,
const uint8_t *id)
{
const struct snand_id *fid;
uint32_t i;
for (i = 0; i < ARRAY_SIZE(snand_flash_ids); i++) {
if (snand_flash_ids[i].id.type != type)
continue;
fid = &snand_flash_ids[i].id;
if (memcmp(fid->id, id, fid->len))
continue;
return &snand_flash_ids[i];
}
return NULL;
}

View file

@ -0,0 +1,681 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
*
* Author: Weijie Gao <weijie.gao@mediatek.com>
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/clk.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
#include <linux/wait.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/of_platform.h>
#include "mtk-snand.h"
#include "mtk-snand-os.h"
struct mtk_snand_of_id {
enum mtk_snand_soc soc;
};
struct mtk_snand_mtd {
struct mtk_snand_plat_dev pdev;
struct clk *nfi_clk;
struct clk *pad_clk;
struct clk *ecc_clk;
void __iomem *nfi_regs;
void __iomem *ecc_regs;
int irq;
bool quad_spi;
enum mtk_snand_soc soc;
struct mtd_info mtd;
struct mtk_snand *snf;
struct mtk_snand_chip_info cinfo;
uint8_t *page_cache;
struct mutex lock;
};
#define mtd_to_msm(mtd) container_of(mtd, struct mtk_snand_mtd, mtd)
static int mtk_snand_mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
{
struct mtk_snand_mtd *msm = mtd_to_msm(mtd);
u64 start_addr, end_addr;
int ret;
/* Do not allow write past end of device */
if ((instr->addr + instr->len) > msm->cinfo.chipsize) {
dev_err(msm->pdev.dev,
"attempt to erase beyond end of device\n");
return -EINVAL;
}
start_addr = instr->addr & (~mtd->erasesize_mask);
end_addr = instr->addr + instr->len;
if (end_addr & mtd->erasesize_mask) {
end_addr = (end_addr + mtd->erasesize_mask) &
(~mtd->erasesize_mask);
}
mutex_lock(&msm->lock);
while (start_addr < end_addr) {
if (mtk_snand_block_isbad(msm->snf, start_addr)) {
instr->fail_addr = start_addr;
ret = -EIO;
break;
}
ret = mtk_snand_erase_block(msm->snf, start_addr);
if (ret) {
instr->fail_addr = start_addr;
break;
}
start_addr += mtd->erasesize;
}
mutex_unlock(&msm->lock);
return ret;
}
static int mtk_snand_mtd_read_data(struct mtk_snand_mtd *msm, uint64_t addr,
struct mtd_oob_ops *ops)
{
struct mtd_info *mtd = &msm->mtd;
size_t len, ooblen, maxooblen, chklen;
uint32_t col, ooboffs;
uint8_t *datcache, *oobcache;
bool ecc_failed = false, raw = ops->mode == MTD_OPS_RAW ? true : false;
int ret, max_bitflips = 0;
col = addr & mtd->writesize_mask;
addr &= ~mtd->writesize_mask;
maxooblen = mtd_oobavail(mtd, ops);
ooboffs = ops->ooboffs;
ooblen = ops->ooblen;
len = ops->len;
datcache = len ? msm->page_cache : NULL;
oobcache = ooblen ? msm->page_cache + mtd->writesize : NULL;
ops->oobretlen = 0;
ops->retlen = 0;
while (len || ooblen) {
if (ops->mode == MTD_OPS_AUTO_OOB)
ret = mtk_snand_read_page_auto_oob(msm->snf, addr,
datcache, oobcache, maxooblen, NULL, raw);
else
ret = mtk_snand_read_page(msm->snf, addr, datcache,
oobcache, raw);
if (ret < 0 && ret != -EBADMSG)
return ret;
if (ret == -EBADMSG) {
mtd->ecc_stats.failed++;
ecc_failed = true;
} else {
mtd->ecc_stats.corrected += ret;
max_bitflips = max_t(int, ret, max_bitflips);
}
if (len) {
/* Move data */
chklen = mtd->writesize - col;
if (chklen > len)
chklen = len;
memcpy(ops->datbuf + ops->retlen, datcache + col,
chklen);
len -= chklen;
col = 0; /* (col + chklen) % */
ops->retlen += chklen;
}
if (ooblen) {
/* Move oob */
chklen = maxooblen - ooboffs;
if (chklen > ooblen)
chklen = ooblen;
memcpy(ops->oobbuf + ops->oobretlen, oobcache + ooboffs,
chklen);
ooblen -= chklen;
ooboffs = 0; /* (ooboffs + chklen) % maxooblen; */
ops->oobretlen += chklen;
}
addr += mtd->writesize;
}
return ecc_failed ? -EBADMSG : max_bitflips;
}
static int mtk_snand_mtd_read_oob(struct mtd_info *mtd, loff_t from,
struct mtd_oob_ops *ops)
{
struct mtk_snand_mtd *msm = mtd_to_msm(mtd);
uint32_t maxooblen;
int ret;
if (!ops->oobbuf && !ops->datbuf) {
if (ops->ooblen || ops->len)
return -EINVAL;
return 0;
}
switch (ops->mode) {
case MTD_OPS_PLACE_OOB:
case MTD_OPS_AUTO_OOB:
case MTD_OPS_RAW:
break;
default:
dev_err(msm->pdev.dev, "unsupported oob mode: %u\n", ops->mode);
return -EINVAL;
}
maxooblen = mtd_oobavail(mtd, ops);
/* Do not allow read past end of device */
if (ops->datbuf && (from + ops->len) > msm->cinfo.chipsize) {
dev_err(msm->pdev.dev,
"attempt to read beyond end of device\n");
return -EINVAL;
}
if (unlikely(ops->ooboffs >= maxooblen)) {
dev_err(msm->pdev.dev, "attempt to start read outside oob\n");
return -EINVAL;
}
if (unlikely(from >= msm->cinfo.chipsize ||
ops->ooboffs + ops->ooblen >
((msm->cinfo.chipsize >> mtd->writesize_shift) -
(from >> mtd->writesize_shift)) *
maxooblen)) {
dev_err(msm->pdev.dev,
"attempt to read beyond end of device\n");
return -EINVAL;
}
mutex_lock(&msm->lock);
ret = mtk_snand_mtd_read_data(msm, from, ops);
mutex_unlock(&msm->lock);
return ret;
}
static int mtk_snand_mtd_write_data(struct mtk_snand_mtd *msm, uint64_t addr,
struct mtd_oob_ops *ops)
{
struct mtd_info *mtd = &msm->mtd;
size_t len, ooblen, maxooblen, chklen, oobwrlen;
uint32_t col, ooboffs;
uint8_t *datcache, *oobcache;
bool raw = ops->mode == MTD_OPS_RAW ? true : false;
int ret;
col = addr & mtd->writesize_mask;
addr &= ~mtd->writesize_mask;
maxooblen = mtd_oobavail(mtd, ops);
ooboffs = ops->ooboffs;
ooblen = ops->ooblen;
len = ops->len;
datcache = len ? msm->page_cache : NULL;
oobcache = ooblen ? msm->page_cache + mtd->writesize : NULL;
ops->oobretlen = 0;
ops->retlen = 0;
while (len || ooblen) {
if (len) {
/* Move data */
chklen = mtd->writesize - col;
if (chklen > len)
chklen = len;
memset(datcache, 0xff, col);
memcpy(datcache + col, ops->datbuf + ops->retlen,
chklen);
memset(datcache + col + chklen, 0xff,
mtd->writesize - col - chklen);
len -= chklen;
col = 0; /* (col + chklen) % */
ops->retlen += chklen;
}
oobwrlen = 0;
if (ooblen) {
/* Move oob */
chklen = maxooblen - ooboffs;
if (chklen > ooblen)
chklen = ooblen;
memset(oobcache, 0xff, ooboffs);
memcpy(oobcache + ooboffs,
ops->oobbuf + ops->oobretlen, chklen);
memset(oobcache + ooboffs + chklen, 0xff,
mtd->oobsize - ooboffs - chklen);
oobwrlen = chklen + ooboffs;
ooblen -= chklen;
ooboffs = 0; /* (ooboffs + chklen) % maxooblen; */
ops->oobretlen += chklen;
}
if (ops->mode == MTD_OPS_AUTO_OOB)
ret = mtk_snand_write_page_auto_oob(msm->snf, addr,
datcache, oobcache, oobwrlen, NULL, raw);
else
ret = mtk_snand_write_page(msm->snf, addr, datcache,
oobcache, raw);
if (ret)
return ret;
addr += mtd->writesize;
}
return 0;
}
static int mtk_snand_mtd_write_oob(struct mtd_info *mtd, loff_t to,
struct mtd_oob_ops *ops)
{
struct mtk_snand_mtd *msm = mtd_to_msm(mtd);
uint32_t maxooblen;
int ret;
if (!ops->oobbuf && !ops->datbuf) {
if (ops->ooblen || ops->len)
return -EINVAL;
return 0;
}
switch (ops->mode) {
case MTD_OPS_PLACE_OOB:
case MTD_OPS_AUTO_OOB:
case MTD_OPS_RAW:
break;
default:
dev_err(msm->pdev.dev, "unsupported oob mode: %u\n", ops->mode);
return -EINVAL;
}
maxooblen = mtd_oobavail(mtd, ops);
/* Do not allow write past end of device */
if (ops->datbuf && (to + ops->len) > msm->cinfo.chipsize) {
dev_err(msm->pdev.dev,
"attempt to write beyond end of device\n");
return -EINVAL;
}
if (unlikely(ops->ooboffs >= maxooblen)) {
dev_err(msm->pdev.dev,
"attempt to start write outside oob\n");
return -EINVAL;
}
if (unlikely(to >= msm->cinfo.chipsize ||
ops->ooboffs + ops->ooblen >
((msm->cinfo.chipsize >> mtd->writesize_shift) -
(to >> mtd->writesize_shift)) *
maxooblen)) {
dev_err(msm->pdev.dev,
"attempt to write beyond end of device\n");
return -EINVAL;
}
mutex_lock(&msm->lock);
ret = mtk_snand_mtd_write_data(msm, to, ops);
mutex_unlock(&msm->lock);
return ret;
}
static int mtk_snand_mtd_block_isbad(struct mtd_info *mtd, loff_t offs)
{
struct mtk_snand_mtd *msm = mtd_to_msm(mtd);
int ret;
mutex_lock(&msm->lock);
ret = mtk_snand_block_isbad(msm->snf, offs);
mutex_unlock(&msm->lock);
return ret;
}
static int mtk_snand_mtd_block_markbad(struct mtd_info *mtd, loff_t offs)
{
struct mtk_snand_mtd *msm = mtd_to_msm(mtd);
int ret;
mutex_lock(&msm->lock);
ret = mtk_snand_block_markbad(msm->snf, offs);
mutex_unlock(&msm->lock);
return ret;
}
static int mtk_snand_ooblayout_ecc(struct mtd_info *mtd, int section,
struct mtd_oob_region *oobecc)
{
struct mtk_snand_mtd *msm = mtd_to_msm(mtd);
if (section)
return -ERANGE;
oobecc->offset = msm->cinfo.fdm_size * msm->cinfo.num_sectors;
oobecc->length = mtd->oobsize - oobecc->offset;
return 0;
}
static int mtk_snand_ooblayout_free(struct mtd_info *mtd, int section,
struct mtd_oob_region *oobfree)
{
struct mtk_snand_mtd *msm = mtd_to_msm(mtd);
if (section >= msm->cinfo.num_sectors)
return -ERANGE;
oobfree->length = msm->cinfo.fdm_size - 1;
oobfree->offset = section * msm->cinfo.fdm_size + 1;
return 0;
}
static irqreturn_t mtk_snand_irq(int irq, void *id)
{
struct mtk_snand_mtd *msm = id;
int ret;
ret = mtk_snand_irq_process(msm->snf);
if (ret > 0)
return IRQ_HANDLED;
return IRQ_NONE;
}
static int mtk_snand_enable_clk(struct mtk_snand_mtd *msm)
{
int ret;
ret = clk_prepare_enable(msm->nfi_clk);
if (ret) {
dev_err(msm->pdev.dev, "unable to enable nfi clk\n");
return ret;
}
ret = clk_prepare_enable(msm->pad_clk);
if (ret) {
dev_err(msm->pdev.dev, "unable to enable pad clk\n");
clk_disable_unprepare(msm->nfi_clk);
return ret;
}
ret = clk_prepare_enable(msm->ecc_clk);
if (ret) {
dev_err(msm->pdev.dev, "unable to enable ecc clk\n");
clk_disable_unprepare(msm->nfi_clk);
clk_disable_unprepare(msm->pad_clk);
return ret;
}
return 0;
}
static void mtk_snand_disable_clk(struct mtk_snand_mtd *msm)
{
clk_disable_unprepare(msm->nfi_clk);
clk_disable_unprepare(msm->pad_clk);
clk_disable_unprepare(msm->ecc_clk);
}
static const struct mtd_ooblayout_ops mtk_snand_ooblayout = {
.ecc = mtk_snand_ooblayout_ecc,
.free = mtk_snand_ooblayout_free,
};
static struct mtk_snand_of_id mt7622_soc_id = { .soc = SNAND_SOC_MT7622 };
static struct mtk_snand_of_id mt7629_soc_id = { .soc = SNAND_SOC_MT7629 };
static const struct of_device_id mtk_snand_ids[] = {
{ .compatible = "mediatek,mt7622-snand", .data = &mt7622_soc_id },
{ .compatible = "mediatek,mt7629-snand", .data = &mt7629_soc_id },
{ },
};
MODULE_DEVICE_TABLE(of, mtk_snand_ids);
static int mtk_snand_probe(struct platform_device *pdev)
{
struct mtk_snand_platdata mtk_snand_pdata = {};
struct device_node *np = pdev->dev.of_node;
const struct of_device_id *of_soc_id;
const struct mtk_snand_of_id *soc_id;
struct mtk_snand_mtd *msm;
struct mtd_info *mtd;
struct resource *r;
uint32_t size;
int ret;
of_soc_id = of_match_node(mtk_snand_ids, np);
if (!of_soc_id)
return -EINVAL;
soc_id = of_soc_id->data;
msm = devm_kzalloc(&pdev->dev, sizeof(*msm), GFP_KERNEL);
if (!msm)
return -ENOMEM;
r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nfi");
msm->nfi_regs = devm_ioremap_resource(&pdev->dev, r);
if (IS_ERR(msm->nfi_regs)) {
ret = PTR_ERR(msm->nfi_regs);
goto errout1;
}
r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ecc");
msm->ecc_regs = devm_ioremap_resource(&pdev->dev, r);
if (IS_ERR(msm->ecc_regs)) {
ret = PTR_ERR(msm->ecc_regs);
goto errout1;
}
msm->pdev.dev = &pdev->dev;
msm->quad_spi = of_property_read_bool(np, "mediatek,quad-spi");
msm->soc = soc_id->soc;
msm->nfi_clk = devm_clk_get(msm->pdev.dev, "nfi_clk");
if (IS_ERR(msm->nfi_clk)) {
ret = PTR_ERR(msm->nfi_clk);
dev_err(msm->pdev.dev, "unable to get nfi_clk, err = %d\n",
ret);
goto errout1;
}
msm->ecc_clk = devm_clk_get(msm->pdev.dev, "ecc_clk");
if (IS_ERR(msm->ecc_clk)) {
ret = PTR_ERR(msm->ecc_clk);
dev_err(msm->pdev.dev, "unable to get ecc_clk, err = %d\n",
ret);
goto errout1;
}
msm->pad_clk = devm_clk_get(msm->pdev.dev, "pad_clk");
if (IS_ERR(msm->pad_clk)) {
ret = PTR_ERR(msm->pad_clk);
dev_err(msm->pdev.dev, "unable to get pad_clk, err = %d\n",
ret);
goto errout1;
}
ret = mtk_snand_enable_clk(msm);
if (ret)
goto errout1;
/* Probe SPI-NAND Flash */
mtk_snand_pdata.soc = msm->soc;
mtk_snand_pdata.quad_spi = msm->quad_spi;
mtk_snand_pdata.nfi_base = msm->nfi_regs;
mtk_snand_pdata.ecc_base = msm->ecc_regs;
ret = mtk_snand_init(&msm->pdev, &mtk_snand_pdata, &msm->snf);
if (ret)
goto errout1;
msm->irq = platform_get_irq(pdev, 0);
if (msm->irq >= 0) {
ret = devm_request_irq(msm->pdev.dev, msm->irq, mtk_snand_irq,
0x0, "mtk-snand", msm);
if (ret) {
dev_err(msm->pdev.dev, "failed to request snfi irq\n");
goto errout2;
}
ret = dma_set_mask(msm->pdev.dev, DMA_BIT_MASK(32));
if (ret) {
dev_err(msm->pdev.dev, "failed to set dma mask\n");
goto errout3;
}
}
mtk_snand_get_chip_info(msm->snf, &msm->cinfo);
size = msm->cinfo.pagesize + msm->cinfo.sparesize;
msm->page_cache = devm_kmalloc(msm->pdev.dev, size, GFP_KERNEL);
if (!msm->page_cache) {
dev_err(msm->pdev.dev, "failed to allocate page cache\n");
ret = -ENOMEM;
goto errout3;
}
mutex_init(&msm->lock);
dev_info(msm->pdev.dev,
"chip is %s, size %lluMB, page size %u, oob size %u\n",
msm->cinfo.model, msm->cinfo.chipsize >> 20,
msm->cinfo.pagesize, msm->cinfo.sparesize);
/* Initialize mtd for SPI-NAND */
mtd = &msm->mtd;
mtd->owner = THIS_MODULE;
mtd->dev.parent = &pdev->dev;
mtd->type = MTD_NANDFLASH;
mtd->flags = MTD_CAP_NANDFLASH;
mtd_set_of_node(mtd, np);
mtd->size = msm->cinfo.chipsize;
mtd->erasesize = msm->cinfo.blocksize;
mtd->writesize = msm->cinfo.pagesize;
mtd->writebufsize = mtd->writesize;
mtd->oobsize = msm->cinfo.sparesize;
mtd->oobavail = msm->cinfo.num_sectors * (msm->cinfo.fdm_size - 1);
mtd->erasesize_shift = ffs(mtd->erasesize) - 1;
mtd->writesize_shift = ffs(mtd->writesize) - 1;
mtd->erasesize_mask = (1 << mtd->erasesize_shift) - 1;
mtd->writesize_mask = (1 << mtd->writesize_shift) - 1;
mtd->ooblayout = &mtk_snand_ooblayout;
mtd->ecc_strength = msm->cinfo.ecc_strength;
mtd->bitflip_threshold = (mtd->ecc_strength * 3) / 4;
mtd->ecc_step_size = msm->cinfo.sector_size;
mtd->_erase = mtk_snand_mtd_erase;
mtd->_read_oob = mtk_snand_mtd_read_oob;
mtd->_write_oob = mtk_snand_mtd_write_oob;
mtd->_block_isbad = mtk_snand_mtd_block_isbad;
mtd->_block_markbad = mtk_snand_mtd_block_markbad;
ret = mtd_device_register(mtd, NULL, 0);
if (ret) {
dev_err(msm->pdev.dev, "failed to register mtd partition\n");
goto errout4;
}
platform_set_drvdata(pdev, msm);
return 0;
errout4:
devm_kfree(msm->pdev.dev, msm->page_cache);
errout3:
if (msm->irq >= 0)
devm_free_irq(msm->pdev.dev, msm->irq, msm);
errout2:
mtk_snand_cleanup(msm->snf);
errout1:
devm_kfree(msm->pdev.dev, msm);
platform_set_drvdata(pdev, NULL);
return ret;
}
static int mtk_snand_remove(struct platform_device *pdev)
{
struct mtk_snand_mtd *msm = platform_get_drvdata(pdev);
struct mtd_info *mtd = &msm->mtd;
int ret;
ret = mtd_device_unregister(mtd);
if (ret)
return ret;
mtk_snand_cleanup(msm->snf);
if (msm->irq >= 0)
devm_free_irq(msm->pdev.dev, msm->irq, msm);
mtk_snand_disable_clk(msm);
devm_kfree(msm->pdev.dev, msm->page_cache);
devm_kfree(msm->pdev.dev, msm);
platform_set_drvdata(pdev, NULL);
return 0;
}
static struct platform_driver mtk_snand_driver = {
.probe = mtk_snand_probe,
.remove = mtk_snand_remove,
.driver = {
.name = "mtk-snand",
.of_match_table = mtk_snand_ids,
},
};
module_platform_driver(mtk_snand_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Weijie Gao <weijie.gao@mediatek.com>");
MODULE_DESCRIPTION("MeidaTek SPI-NAND Flash Controller Driver");

View file

@ -0,0 +1,48 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
*
* Author: Weijie Gao <weijie.gao@mediatek.com>
*/
#include "mtk-snand-def.h"
int mtk_snand_log(struct mtk_snand_plat_dev *pdev,
enum mtk_snand_log_category cat, const char *fmt, ...)
{
const char *catname = "";
va_list ap;
char *msg;
switch (cat) {
case SNAND_LOG_NFI:
catname = "NFI";
break;
case SNAND_LOG_SNFI:
catname = "SNFI";
break;
case SNAND_LOG_ECC:
catname = "ECC";
break;
default:
break;
}
va_start(ap, fmt);
msg = kvasprintf(GFP_KERNEL, fmt, ap);
va_end(ap);
if (!msg) {
dev_warn(pdev->dev, "unable to print log\n");
return -1;
}
if (*catname)
dev_warn(pdev->dev, "%s: %s", catname, msg);
else
dev_warn(pdev->dev, "%s", msg);
kfree(msg);
return 0;
}

View file

@ -0,0 +1,127 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
*
* Author: Weijie Gao <weijie.gao@mediatek.com>
*/
#ifndef _MTK_SNAND_OS_H_
#define _MTK_SNAND_OS_H_
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/limits.h>
#include <linux/types.h>
#include <linux/bitops.h>
#include <linux/sizes.h>
#include <linux/iopoll.h>
#include <linux/hrtimer.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <asm/div64.h>
struct mtk_snand_plat_dev {
struct device *dev;
struct completion done;
};
/* Polling helpers */
#define read16_poll_timeout(addr, val, cond, sleep_us, timeout_us) \
readw_poll_timeout((addr), (val), (cond), (sleep_us), (timeout_us))
#define read32_poll_timeout(addr, val, cond, sleep_us, timeout_us) \
readl_poll_timeout((addr), (val), (cond), (sleep_us), (timeout_us))
/* Timer helpers */
#define mtk_snand_time_t ktime_t
static inline mtk_snand_time_t timer_get_ticks(void)
{
return ktime_get();
}
static inline mtk_snand_time_t timer_time_to_tick(uint32_t timeout_us)
{
return ktime_add_us(ktime_set(0, 0), timeout_us);
}
static inline bool timer_is_timeout(mtk_snand_time_t start_tick,
mtk_snand_time_t timeout_tick)
{
ktime_t tmo = ktime_add(start_tick, timeout_tick);
return ktime_compare(ktime_get(), tmo) > 0;
}
/* Memory helpers */
static inline void *generic_mem_alloc(struct mtk_snand_plat_dev *pdev,
size_t size)
{
return devm_kzalloc(pdev->dev, size, GFP_KERNEL);
}
static inline void generic_mem_free(struct mtk_snand_plat_dev *pdev, void *ptr)
{
devm_kfree(pdev->dev, ptr);
}
static inline void *dma_mem_alloc(struct mtk_snand_plat_dev *pdev, size_t size)
{
return kzalloc(size, GFP_KERNEL);
}
static inline void dma_mem_free(struct mtk_snand_plat_dev *pdev, void *ptr)
{
kfree(ptr);
}
static inline int dma_mem_map(struct mtk_snand_plat_dev *pdev, void *vaddr,
uintptr_t *dma_addr, size_t size, bool to_device)
{
dma_addr_t addr;
int ret;
addr = dma_map_single(pdev->dev, vaddr, size,
to_device ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
ret = dma_mapping_error(pdev->dev, addr);
if (ret)
return ret;
*dma_addr = (uintptr_t)addr;
return 0;
}
static inline void dma_mem_unmap(struct mtk_snand_plat_dev *pdev,
uintptr_t dma_addr, size_t size,
bool to_device)
{
dma_unmap_single(pdev->dev, dma_addr, size,
to_device ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
}
/* Interrupt helpers */
static inline void irq_completion_done(struct mtk_snand_plat_dev *pdev)
{
complete(&pdev->done);
}
static inline void irq_completion_init(struct mtk_snand_plat_dev *pdev)
{
init_completion(&pdev->done);
}
static inline int irq_completion_wait(struct mtk_snand_plat_dev *pdev,
void __iomem *reg, uint32_t bit,
uint32_t timeout_us)
{
int ret;
ret = wait_for_completion_timeout(&pdev->done,
usecs_to_jiffies(timeout_us));
if (!ret)
return -ETIMEDOUT;
return 0;
}
#endif /* _MTK_SNAND_OS_H_ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,76 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
*
* Author: Weijie Gao <weijie.gao@mediatek.com>
*/
#ifndef _MTK_SNAND_H_
#define _MTK_SNAND_H_
#ifndef PRIVATE_MTK_SNAND_HEADER
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#endif
enum mtk_snand_soc {
SNAND_SOC_MT7622,
SNAND_SOC_MT7629,
__SNAND_SOC_MAX
};
struct mtk_snand_platdata {
void *nfi_base;
void *ecc_base;
enum mtk_snand_soc soc;
bool quad_spi;
};
struct mtk_snand_chip_info {
const char *model;
uint64_t chipsize;
uint32_t blocksize;
uint32_t pagesize;
uint32_t sparesize;
uint32_t spare_per_sector;
uint32_t fdm_size;
uint32_t fdm_ecc_size;
uint32_t num_sectors;
uint32_t sector_size;
uint32_t ecc_strength;
uint32_t ecc_bytes;
};
struct mtk_snand;
struct snand_flash_info;
int mtk_snand_init(void *dev, const struct mtk_snand_platdata *pdata,
struct mtk_snand **psnf);
int mtk_snand_cleanup(struct mtk_snand *snf);
int mtk_snand_chip_reset(struct mtk_snand *snf);
int mtk_snand_read_page(struct mtk_snand *snf, uint64_t addr, void *buf,
void *oob, bool raw);
int mtk_snand_write_page(struct mtk_snand *snf, uint64_t addr, const void *buf,
const void *oob, bool raw);
int mtk_snand_erase_block(struct mtk_snand *snf, uint64_t addr);
int mtk_snand_block_isbad(struct mtk_snand *snf, uint64_t addr);
int mtk_snand_block_markbad(struct mtk_snand *snf, uint64_t addr);
int mtk_snand_fill_oob(struct mtk_snand *snf, uint8_t *oobraw,
const uint8_t *oobbuf, size_t ooblen);
int mtk_snand_transfer_oob(struct mtk_snand *snf, uint8_t *oobbuf,
size_t ooblen, const uint8_t *oobraw);
int mtk_snand_read_page_auto_oob(struct mtk_snand *snf, uint64_t addr,
void *buf, void *oob, size_t ooblen,
size_t *actualooblen, bool raw);
int mtk_snand_write_page_auto_oob(struct mtk_snand *snf, uint64_t addr,
const void *buf, const void *oob,
size_t ooblen, size_t *actualooblen,
bool raw);
int mtk_snand_get_chip_info(struct mtk_snand *snf,
struct mtk_snand_chip_info *info);
int mtk_snand_irq_process(struct mtk_snand *snf);
#endif /* _MTK_SNAND_H_ */

View file

@ -0,0 +1,3 @@
config MT753X_GSW
tristate "Driver for the MediaTek MT753x switch"

View file

@ -0,0 +1,11 @@
#
# Makefile for MediaTek MT753x gigabit switch
#
obj-$(CONFIG_MT753X_GSW) += mt753x.o
mt753x-$(CONFIG_SWCONFIG) += mt753x_swconfig.o
mt753x-y += mt753x_mdio.o mt7530.o mt7531.o \
mt753x_common.o mt753x_vlan.o \
mt753x_nl.o

View file

@ -0,0 +1,631 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018 MediaTek Inc.
* Author: Weijie Gao <weijie.gao@mediatek.com>
*/
#include <linux/kernel.h>
#include <linux/delay.h>
#include "mt753x.h"
#include "mt753x_regs.h"
/* MT7530 registers */
/* Unique fields of PMCR for MT7530 */
#define FORCE_MODE BIT(15)
/* Unique fields of GMACCR for MT7530 */
#define VLAN_SUPT_NO_S 14
#define VLAN_SUPT_NO_M 0x1c000
#define LATE_COL_DROP BIT(13)
/* Unique fields of (M)HWSTRAP for MT7530 */
#define BOND_OPTION BIT(24)
#define P5_PHY0_SEL BIT(20)
#define CHG_TRAP BIT(16)
#define LOOPDET_DIS BIT(14)
#define P5_INTF_SEL_GMAC5 BIT(13)
#define SMI_ADDR_S 11
#define SMI_ADDR_M 0x1800
#define XTAL_FSEL_S 9
#define XTAL_FSEL_M 0x600
#define P6_INTF_DIS BIT(8)
#define P5_INTF_MODE_RGMII BIT(7)
#define P5_INTF_DIS_S BIT(6)
#define C_MDIO_BPS_S BIT(5)
#define EEPROM_EN_S BIT(4)
/* PHY EEE Register bitmap of define */
#define PHY_DEV07 0x07
#define PHY_DEV07_REG_03C 0x3c
/* PHY Extend Register 0x14 bitmap of define */
#define PHY_EXT_REG_14 0x14
/* Fields of PHY_EXT_REG_14 */
#define PHY_EN_DOWN_SHFIT BIT(4)
/* PHY Token Ring Register 0x10 bitmap of define */
#define PHY_TR_REG_10 0x10
/* PHY Token Ring Register 0x12 bitmap of define */
#define PHY_TR_REG_12 0x12
/* PHY LPI PCS/DSP Control Register bitmap of define */
#define PHY_LPI_REG_11 0x11
/* PHY DEV 0x1e Register bitmap of define */
#define PHY_DEV1E 0x1e
#define PHY_DEV1E_REG_123 0x123
#define PHY_DEV1E_REG_A6 0xa6
/* Values of XTAL_FSEL */
#define XTAL_20MHZ 1
#define XTAL_40MHZ 2
#define XTAL_25MHZ 3
#define P6ECR 0x7830
#define P6_INTF_MODE_TRGMII BIT(0)
#define TRGMII_TXCTRL 0x7a40
#define TRAIN_TXEN BIT(31)
#define TXC_INV BIT(30)
#define TX_DOEO BIT(29)
#define TX_RST BIT(28)
#define TRGMII_TD0_CTRL 0x7a50
#define TRGMII_TD1_CTRL 0x7a58
#define TRGMII_TD2_CTRL 0x7a60
#define TRGMII_TD3_CTRL 0x7a68
#define TRGMII_TXCTL_CTRL 0x7a70
#define TRGMII_TCK_CTRL 0x7a78
#define TRGMII_TD_CTRL(n) (0x7a50 + (n) * 8)
#define NUM_TRGMII_CTRL 6
#define TX_DMPEDRV BIT(31)
#define TX_DM_SR BIT(15)
#define TX_DMERODT BIT(14)
#define TX_DMOECTL BIT(13)
#define TX_TAP_S 8
#define TX_TAP_M 0xf00
#define TX_TRAIN_WD_S 0
#define TX_TRAIN_WD_M 0xff
#define TRGMII_TD0_ODT 0x7a54
#define TRGMII_TD1_ODT 0x7a5c
#define TRGMII_TD2_ODT 0x7a64
#define TRGMII_TD3_ODT 0x7a6c
#define TRGMII_TXCTL_ODT 0x7574
#define TRGMII_TCK_ODT 0x757c
#define TRGMII_TD_ODT(n) (0x7a54 + (n) * 8)
#define NUM_TRGMII_ODT 6
#define TX_DM_DRVN_PRE_S 30
#define TX_DM_DRVN_PRE_M 0xc0000000
#define TX_DM_DRVP_PRE_S 28
#define TX_DM_DRVP_PRE_M 0x30000000
#define TX_DM_TDSEL_S 24
#define TX_DM_TDSEL_M 0xf000000
#define TX_ODTEN BIT(23)
#define TX_DME_PRE BIT(20)
#define TX_DM_DRVNT0 BIT(19)
#define TX_DM_DRVPT0 BIT(18)
#define TX_DM_DRVNTE BIT(17)
#define TX_DM_DRVPTE BIT(16)
#define TX_DM_ODTN_S 12
#define TX_DM_ODTN_M 0x7000
#define TX_DM_ODTP_S 8
#define TX_DM_ODTP_M 0x700
#define TX_DM_DRVN_S 4
#define TX_DM_DRVN_M 0xf0
#define TX_DM_DRVP_S 0
#define TX_DM_DRVP_M 0x0f
#define P5RGMIIRXCR 0x7b00
#define CSR_RGMII_RCTL_CFG_S 24
#define CSR_RGMII_RCTL_CFG_M 0x7000000
#define CSR_RGMII_RXD_CFG_S 16
#define CSR_RGMII_RXD_CFG_M 0x70000
#define CSR_RGMII_EDGE_ALIGN BIT(8)
#define CSR_RGMII_RXC_90DEG_CFG_S 4
#define CSR_RGMII_RXC_90DEG_CFG_M 0xf0
#define CSR_RGMII_RXC_0DEG_CFG_S 0
#define CSR_RGMII_RXC_0DEG_CFG_M 0x0f
#define P5RGMIITXCR 0x7b04
#define CSR_RGMII_TXEN_CFG_S 16
#define CSR_RGMII_TXEN_CFG_M 0x70000
#define CSR_RGMII_TXD_CFG_S 8
#define CSR_RGMII_TXD_CFG_M 0x700
#define CSR_RGMII_TXC_CFG_S 0
#define CSR_RGMII_TXC_CFG_M 0x1f
#define CHIP_REV 0x7ffc
#define CHIP_NAME_S 16
#define CHIP_NAME_M 0xffff0000
#define CHIP_REV_S 0
#define CHIP_REV_M 0x0f
/* MMD registers */
#define CORE_PLL_GROUP2 0x401
#define RG_SYSPLL_EN_NORMAL BIT(15)
#define RG_SYSPLL_VODEN BIT(14)
#define RG_SYSPLL_POSDIV_S 5
#define RG_SYSPLL_POSDIV_M 0x60
#define CORE_PLL_GROUP4 0x403
#define RG_SYSPLL_DDSFBK_EN BIT(12)
#define RG_SYSPLL_BIAS_EN BIT(11)
#define RG_SYSPLL_BIAS_LPF_EN BIT(10)
#define CORE_PLL_GROUP5 0x404
#define RG_LCDDS_PCW_NCPO1_S 0
#define RG_LCDDS_PCW_NCPO1_M 0xffff
#define CORE_PLL_GROUP6 0x405
#define RG_LCDDS_PCW_NCPO0_S 0
#define RG_LCDDS_PCW_NCPO0_M 0xffff
#define CORE_PLL_GROUP7 0x406
#define RG_LCDDS_PWDB BIT(15)
#define RG_LCDDS_ISO_EN BIT(13)
#define RG_LCCDS_C_S 4
#define RG_LCCDS_C_M 0x70
#define RG_LCDDS_PCW_NCPO_CHG BIT(3)
#define CORE_PLL_GROUP10 0x409
#define RG_LCDDS_SSC_DELTA_S 0
#define RG_LCDDS_SSC_DELTA_M 0xfff
#define CORE_PLL_GROUP11 0x40a
#define RG_LCDDS_SSC_DELTA1_S 0
#define RG_LCDDS_SSC_DELTA1_M 0xfff
#define CORE_GSWPLL_GCR_1 0x040d
#define GSWPLL_PREDIV_S 14
#define GSWPLL_PREDIV_M 0xc000
#define GSWPLL_POSTDIV_200M_S 12
#define GSWPLL_POSTDIV_200M_M 0x3000
#define GSWPLL_EN_PRE BIT(11)
#define GSWPLL_FBKSEL BIT(10)
#define GSWPLL_BP BIT(9)
#define GSWPLL_BR BIT(8)
#define GSWPLL_FBKDIV_200M_S 0
#define GSWPLL_FBKDIV_200M_M 0xff
#define CORE_GSWPLL_GCR_2 0x040e
#define GSWPLL_POSTDIV_500M_S 8
#define GSWPLL_POSTDIV_500M_M 0x300
#define GSWPLL_FBKDIV_500M_S 0
#define GSWPLL_FBKDIV_500M_M 0xff
#define TRGMII_GSW_CLK_CG 0x0410
#define TRGMIICK_EN BIT(1)
#define GSWCK_EN BIT(0)
static int mt7530_mii_read(struct gsw_mt753x *gsw, int phy, int reg)
{
if (phy < MT753X_NUM_PHYS)
phy = (gsw->phy_base + phy) & MT753X_SMI_ADDR_MASK;
return mdiobus_read(gsw->host_bus, phy, reg);
}
static void mt7530_mii_write(struct gsw_mt753x *gsw, int phy, int reg, u16 val)
{
if (phy < MT753X_NUM_PHYS)
phy = (gsw->phy_base + phy) & MT753X_SMI_ADDR_MASK;
mdiobus_write(gsw->host_bus, phy, reg, val);
}
static int mt7530_mmd_read(struct gsw_mt753x *gsw, int addr, int devad, u16 reg)
{
u16 val;
if (addr < MT753X_NUM_PHYS)
addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK;
mutex_lock(&gsw->host_bus->mdio_lock);
gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ACC_CTL_REG,
(MMD_ADDR << MMD_CMD_S) |
((devad << MMD_DEVAD_S) & MMD_DEVAD_M));
gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ADDR_DATA_REG, reg);
gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ACC_CTL_REG,
(MMD_DATA << MMD_CMD_S) |
((devad << MMD_DEVAD_S) & MMD_DEVAD_M));
val = gsw->host_bus->read(gsw->host_bus, addr, MII_MMD_ADDR_DATA_REG);
mutex_unlock(&gsw->host_bus->mdio_lock);
return val;
}
static void mt7530_mmd_write(struct gsw_mt753x *gsw, int addr, int devad,
u16 reg, u16 val)
{
if (addr < MT753X_NUM_PHYS)
addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK;
mutex_lock(&gsw->host_bus->mdio_lock);
gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ACC_CTL_REG,
(MMD_ADDR << MMD_CMD_S) |
((devad << MMD_DEVAD_S) & MMD_DEVAD_M));
gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ADDR_DATA_REG, reg);
gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ACC_CTL_REG,
(MMD_DATA << MMD_CMD_S) |
((devad << MMD_DEVAD_S) & MMD_DEVAD_M));
gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ADDR_DATA_REG, val);
mutex_unlock(&gsw->host_bus->mdio_lock);
}
static void mt7530_core_reg_write(struct gsw_mt753x *gsw, u32 reg, u32 val)
{
gsw->mmd_write(gsw, 0, 0x1f, reg, val);
}
static void mt7530_trgmii_setting(struct gsw_mt753x *gsw)
{
u16 i;
mt7530_core_reg_write(gsw, CORE_PLL_GROUP5, 0x0780);
mdelay(1);
mt7530_core_reg_write(gsw, CORE_PLL_GROUP6, 0);
mt7530_core_reg_write(gsw, CORE_PLL_GROUP10, 0x87);
mdelay(1);
mt7530_core_reg_write(gsw, CORE_PLL_GROUP11, 0x87);
/* PLL BIAS enable */
mt7530_core_reg_write(gsw, CORE_PLL_GROUP4,
RG_SYSPLL_DDSFBK_EN | RG_SYSPLL_BIAS_EN);
mdelay(1);
/* PLL LPF enable */
mt7530_core_reg_write(gsw, CORE_PLL_GROUP4,
RG_SYSPLL_DDSFBK_EN |
RG_SYSPLL_BIAS_EN | RG_SYSPLL_BIAS_LPF_EN);
/* sys PLL enable */
mt7530_core_reg_write(gsw, CORE_PLL_GROUP2,
RG_SYSPLL_EN_NORMAL | RG_SYSPLL_VODEN |
(1 << RG_SYSPLL_POSDIV_S));
/* LCDDDS PWDS */
mt7530_core_reg_write(gsw, CORE_PLL_GROUP7,
(3 << RG_LCCDS_C_S) |
RG_LCDDS_PWDB | RG_LCDDS_ISO_EN);
mdelay(1);
/* Enable MT7530 TRGMII clock */
mt7530_core_reg_write(gsw, TRGMII_GSW_CLK_CG, GSWCK_EN | TRGMIICK_EN);
/* lower Tx Driving */
for (i = 0 ; i < NUM_TRGMII_ODT; i++)
mt753x_reg_write(gsw, TRGMII_TD_ODT(i),
(4 << TX_DM_DRVP_S) | (4 << TX_DM_DRVN_S));
}
static void mt7530_rgmii_setting(struct gsw_mt753x *gsw)
{
u32 val;
mt7530_core_reg_write(gsw, CORE_PLL_GROUP5, 0x0c80);
mdelay(1);
mt7530_core_reg_write(gsw, CORE_PLL_GROUP6, 0);
mt7530_core_reg_write(gsw, CORE_PLL_GROUP10, 0x87);
mdelay(1);
mt7530_core_reg_write(gsw, CORE_PLL_GROUP11, 0x87);
val = mt753x_reg_read(gsw, TRGMII_TXCTRL);
val &= ~TXC_INV;
mt753x_reg_write(gsw, TRGMII_TXCTRL, val);
mt753x_reg_write(gsw, TRGMII_TCK_CTRL,
(8 << TX_TAP_S) | (0x55 << TX_TRAIN_WD_S));
}
static int mt7530_mac_port_setup(struct gsw_mt753x *gsw)
{
u32 hwstrap, p6ecr = 0, p5mcr, p6mcr, phyad;
hwstrap = mt753x_reg_read(gsw, MHWSTRAP);
hwstrap &= ~(P6_INTF_DIS | P5_INTF_MODE_RGMII | P5_INTF_DIS_S);
hwstrap |= P5_INTF_SEL_GMAC5;
if (!gsw->port5_cfg.enabled) {
p5mcr = FORCE_MODE;
hwstrap |= P5_INTF_DIS_S;
} else {
p5mcr = (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) |
MAC_MODE | MAC_TX_EN | MAC_RX_EN |
BKOFF_EN | BACKPR_EN;
if (gsw->port5_cfg.force_link) {
p5mcr |= FORCE_MODE | FORCE_LINK | FORCE_RX_FC |
FORCE_TX_FC;
p5mcr |= gsw->port5_cfg.speed << FORCE_SPD_S;
if (gsw->port5_cfg.duplex)
p5mcr |= FORCE_DPX;
}
switch (gsw->port5_cfg.phy_mode) {
case PHY_INTERFACE_MODE_MII:
case PHY_INTERFACE_MODE_GMII:
break;
case PHY_INTERFACE_MODE_RGMII:
hwstrap |= P5_INTF_MODE_RGMII;
break;
default:
dev_info(gsw->dev, "%s is not supported by port5\n",
phy_modes(gsw->port5_cfg.phy_mode));
p5mcr = FORCE_MODE;
hwstrap |= P5_INTF_DIS_S;
}
/* Port5 to PHY direct mode */
if (of_property_read_u32(gsw->port5_cfg.np, "phy-address",
&phyad))
goto parse_p6;
if (phyad != 0 && phyad != 4) {
dev_info(gsw->dev,
"Only PHY 0/4 can be connected to Port 5\n");
goto parse_p6;
}
hwstrap &= ~P5_INTF_SEL_GMAC5;
if (phyad == 0)
hwstrap |= P5_PHY0_SEL;
else
hwstrap &= ~P5_PHY0_SEL;
}
parse_p6:
if (!gsw->port6_cfg.enabled) {
p6mcr = FORCE_MODE;
hwstrap |= P6_INTF_DIS;
} else {
p6mcr = (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) |
MAC_MODE | MAC_TX_EN | MAC_RX_EN |
BKOFF_EN | BACKPR_EN;
if (gsw->port6_cfg.force_link) {
p6mcr |= FORCE_MODE | FORCE_LINK | FORCE_RX_FC |
FORCE_TX_FC;
p6mcr |= gsw->port6_cfg.speed << FORCE_SPD_S;
if (gsw->port6_cfg.duplex)
p6mcr |= FORCE_DPX;
}
switch (gsw->port6_cfg.phy_mode) {
case PHY_INTERFACE_MODE_RGMII:
p6ecr = BIT(1);
break;
case PHY_INTERFACE_MODE_TRGMII:
/* set MT7530 central align */
p6ecr = BIT(0);
break;
default:
dev_info(gsw->dev, "%s is not supported by port6\n",
phy_modes(gsw->port6_cfg.phy_mode));
p6mcr = FORCE_MODE;
hwstrap |= P6_INTF_DIS;
}
}
mt753x_reg_write(gsw, MHWSTRAP, hwstrap);
mt753x_reg_write(gsw, P6ECR, p6ecr);
mt753x_reg_write(gsw, PMCR(5), p5mcr);
mt753x_reg_write(gsw, PMCR(6), p6mcr);
return 0;
}
static void mt7530_core_pll_setup(struct gsw_mt753x *gsw)
{
u32 hwstrap;
hwstrap = mt753x_reg_read(gsw, HWSTRAP);
switch ((hwstrap & XTAL_FSEL_M) >> XTAL_FSEL_S) {
case XTAL_40MHZ:
/* Disable MT7530 core clock */
mt7530_core_reg_write(gsw, TRGMII_GSW_CLK_CG, 0);
/* disable MT7530 PLL */
mt7530_core_reg_write(gsw, CORE_GSWPLL_GCR_1,
(2 << GSWPLL_POSTDIV_200M_S) |
(32 << GSWPLL_FBKDIV_200M_S));
/* For MT7530 core clock = 500Mhz */
mt7530_core_reg_write(gsw, CORE_GSWPLL_GCR_2,
(1 << GSWPLL_POSTDIV_500M_S) |
(25 << GSWPLL_FBKDIV_500M_S));
/* Enable MT7530 PLL */
mt7530_core_reg_write(gsw, CORE_GSWPLL_GCR_1,
(2 << GSWPLL_POSTDIV_200M_S) |
(32 << GSWPLL_FBKDIV_200M_S) |
GSWPLL_EN_PRE);
usleep_range(20, 40);
/* Enable MT7530 core clock */
mt7530_core_reg_write(gsw, TRGMII_GSW_CLK_CG, GSWCK_EN);
break;
default:
/* TODO: PLL settings for 20/25MHz */
break;
}
hwstrap = mt753x_reg_read(gsw, HWSTRAP);
hwstrap |= CHG_TRAP;
if (gsw->direct_phy_access)
hwstrap &= ~C_MDIO_BPS_S;
else
hwstrap |= C_MDIO_BPS_S;
mt753x_reg_write(gsw, MHWSTRAP, hwstrap);
if (gsw->port6_cfg.enabled &&
gsw->port6_cfg.phy_mode == PHY_INTERFACE_MODE_TRGMII) {
mt7530_trgmii_setting(gsw);
} else {
/* RGMII */
mt7530_rgmii_setting(gsw);
}
/* delay setting for 10/1000M */
mt753x_reg_write(gsw, P5RGMIIRXCR,
CSR_RGMII_EDGE_ALIGN |
(2 << CSR_RGMII_RXC_0DEG_CFG_S));
mt753x_reg_write(gsw, P5RGMIITXCR, 0x14 << CSR_RGMII_TXC_CFG_S);
}
static int mt7530_sw_detect(struct gsw_mt753x *gsw, struct chip_rev *crev)
{
u32 rev;
rev = mt753x_reg_read(gsw, CHIP_REV);
if (((rev & CHIP_NAME_M) >> CHIP_NAME_S) == MT7530) {
if (crev) {
crev->rev = rev & CHIP_REV_M;
crev->name = "MT7530";
}
return 0;
}
return -ENODEV;
}
static void mt7530_phy_setting(struct gsw_mt753x *gsw)
{
int i;
u32 val;
for (i = 0; i < MT753X_NUM_PHYS; i++) {
/* Disable EEE */
gsw->mmd_write(gsw, i, PHY_DEV07, PHY_DEV07_REG_03C, 0);
/* Enable HW auto downshift */
gsw->mii_write(gsw, i, 0x1f, 0x1);
val = gsw->mii_read(gsw, i, PHY_EXT_REG_14);
val |= PHY_EN_DOWN_SHFIT;
gsw->mii_write(gsw, i, PHY_EXT_REG_14, val);
/* Increase SlvDPSready time */
gsw->mii_write(gsw, i, 0x1f, 0x52b5);
gsw->mii_write(gsw, i, PHY_TR_REG_10, 0xafae);
gsw->mii_write(gsw, i, PHY_TR_REG_12, 0x2f);
gsw->mii_write(gsw, i, PHY_TR_REG_10, 0x8fae);
/* Increase post_update_timer */
gsw->mii_write(gsw, i, 0x1f, 0x3);
gsw->mii_write(gsw, i, PHY_LPI_REG_11, 0x4b);
gsw->mii_write(gsw, i, 0x1f, 0);
/* Adjust 100_mse_threshold */
gsw->mmd_write(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_123, 0xffff);
/* Disable mcc */
gsw->mmd_write(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_A6, 0x300);
}
}
static inline bool get_phy_access_mode(const struct device_node *np)
{
return of_property_read_bool(np, "mt7530,direct-phy-access");
}
static int mt7530_sw_init(struct gsw_mt753x *gsw)
{
int i;
u32 val;
gsw->direct_phy_access = get_phy_access_mode(gsw->dev->of_node);
/* Force MT7530 to use (in)direct PHY access */
val = mt753x_reg_read(gsw, HWSTRAP);
val |= CHG_TRAP;
if (gsw->direct_phy_access)
val &= ~C_MDIO_BPS_S;
else
val |= C_MDIO_BPS_S;
mt753x_reg_write(gsw, MHWSTRAP, val);
/* Read PHY address base from HWSTRAP */
gsw->phy_base = (((val & SMI_ADDR_M) >> SMI_ADDR_S) << 3) + 8;
gsw->phy_base &= MT753X_SMI_ADDR_MASK;
if (gsw->direct_phy_access) {
gsw->mii_read = mt7530_mii_read;
gsw->mii_write = mt7530_mii_write;
gsw->mmd_read = mt7530_mmd_read;
gsw->mmd_write = mt7530_mmd_write;
} else {
gsw->mii_read = mt753x_mii_read;
gsw->mii_write = mt753x_mii_write;
gsw->mmd_read = mt753x_mmd_ind_read;
gsw->mmd_write = mt753x_mmd_ind_write;
}
for (i = 0; i < MT753X_NUM_PHYS; i++) {
val = gsw->mii_read(gsw, i, MII_BMCR);
val |= BMCR_PDOWN;
gsw->mii_write(gsw, i, MII_BMCR, val);
}
/* Force MAC link down before reset */
mt753x_reg_write(gsw, PMCR(5), FORCE_MODE);
mt753x_reg_write(gsw, PMCR(6), FORCE_MODE);
/* Switch soft reset */
/* BUG: sw reset causes gsw int flooding */
mt753x_reg_write(gsw, SYS_CTRL, SW_PHY_RST | SW_SYS_RST | SW_REG_RST);
usleep_range(10, 20);
/* global mac control settings configuration */
mt753x_reg_write(gsw, GMACCR,
LATE_COL_DROP | (15 << MTCC_LMT_S) |
(2 << MAX_RX_JUMBO_S) | RX_PKT_LEN_MAX_JUMBO);
mt7530_core_pll_setup(gsw);
mt7530_mac_port_setup(gsw);
return 0;
}
static int mt7530_sw_post_init(struct gsw_mt753x *gsw)
{
int i;
u32 val;
mt7530_phy_setting(gsw);
for (i = 0; i < MT753X_NUM_PHYS; i++) {
val = gsw->mii_read(gsw, i, MII_BMCR);
val &= ~BMCR_PDOWN;
gsw->mii_write(gsw, i, MII_BMCR, val);
}
return 0;
}
struct mt753x_sw_id mt7530_id = {
.model = MT7530,
.detect = mt7530_sw_detect,
.init = mt7530_sw_init,
.post_init = mt7530_sw_post_init
};

View file

@ -0,0 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018 MediaTek Inc.
*/
#ifndef _MT7530_H_
#define _MT7530_H_
#include "mt753x.h"
extern struct mt753x_sw_id mt7530_id;
#endif /* _MT7530_H_ */

View file

@ -0,0 +1,918 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018 MediaTek Inc.
* Author: Zhanguo Ju <zhanguo.ju@mediatek.com>
*/
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/hrtimer.h>
#include "mt753x.h"
#include "mt753x_regs.h"
/* MT7531 registers */
#define SGMII_REG_BASE 0x5000
#define SGMII_REG_PORT_BASE 0x1000
#define SGMII_REG(p, r) (SGMII_REG_BASE + \
(p) * SGMII_REG_PORT_BASE + (r))
#define PCS_CONTROL_1(p) SGMII_REG(p, 0x00)
#define SGMII_MODE(p) SGMII_REG(p, 0x20)
#define QPHY_PWR_STATE_CTRL(p) SGMII_REG(p, 0xe8)
#define PHYA_CTRL_SIGNAL3(p) SGMII_REG(p, 0x128)
/* Fields of PCS_CONTROL_1 */
#define SGMII_LINK_STATUS BIT(18)
#define SGMII_AN_ENABLE BIT(12)
#define SGMII_AN_RESTART BIT(9)
/* Fields of SGMII_MODE */
#define SGMII_REMOTE_FAULT_DIS BIT(8)
#define SGMII_IF_MODE_FORCE_DUPLEX BIT(4)
#define SGMII_IF_MODE_FORCE_SPEED_S 0x2
#define SGMII_IF_MODE_FORCE_SPEED_M 0x0c
#define SGMII_IF_MODE_ADVERT_AN BIT(1)
/* Values of SGMII_IF_MODE_FORCE_SPEED */
#define SGMII_IF_MODE_FORCE_SPEED_10 0
#define SGMII_IF_MODE_FORCE_SPEED_100 1
#define SGMII_IF_MODE_FORCE_SPEED_1000 2
/* Fields of QPHY_PWR_STATE_CTRL */
#define PHYA_PWD BIT(4)
/* Fields of PHYA_CTRL_SIGNAL3 */
#define RG_TPHY_SPEED_S 2
#define RG_TPHY_SPEED_M 0x0c
/* Values of RG_TPHY_SPEED */
#define RG_TPHY_SPEED_1000 0
#define RG_TPHY_SPEED_2500 1
/* Unique fields of (M)HWSTRAP for MT7531 */
#define XTAL_FSEL_S 7
#define XTAL_FSEL_M BIT(7)
#define PHY_EN BIT(6)
#define CHG_STRAP BIT(8)
/* Efuse Register Define */
#define GBE_EFUSE 0x7bc8
#define GBE_SEL_EFUSE_EN BIT(0)
/* PHY ENABLE Register bitmap define */
#define PHY_DEV1F 0x1f
#define PHY_DEV1F_REG_44 0x44
#define PHY_DEV1F_REG_104 0x104
#define PHY_DEV1F_REG_10A 0x10a
#define PHY_DEV1F_REG_10B 0x10b
#define PHY_DEV1F_REG_10C 0x10c
#define PHY_DEV1F_REG_10D 0x10d
#define PHY_DEV1F_REG_268 0x268
#define PHY_DEV1F_REG_269 0x269
#define PHY_DEV1F_REG_403 0x403
/* Fields of PHY_DEV1F_REG_403 */
#define GBE_EFUSE_SETTING BIT(3)
#define PHY_EN_BYPASS_MODE BIT(4)
#define POWER_ON_OFF BIT(5)
#define PHY_PLL_M GENMASK(9, 8)
#define PHY_PLL_SEL(x) (((x) << 8) & GENMASK(9, 8))
/* PHY EEE Register bitmap of define */
#define PHY_DEV07 0x07
#define PHY_DEV07_REG_03C 0x3c
/* PHY Extend Register 0x14 bitmap of define */
#define PHY_EXT_REG_14 0x14
/* Fields of PHY_EXT_REG_14 */
#define PHY_EN_DOWN_SHFIT BIT(4)
/* PHY Extend Register 0x17 bitmap of define */
#define PHY_EXT_REG_17 0x17
/* Fields of PHY_EXT_REG_17 */
#define PHY_LINKDOWN_POWER_SAVING_EN BIT(4)
/* PHY Token Ring Register 0x10 bitmap of define */
#define PHY_TR_REG_10 0x10
/* PHY Token Ring Register 0x12 bitmap of define */
#define PHY_TR_REG_12 0x12
/* PHY DEV 0x1e Register bitmap of define */
#define PHY_DEV1E 0x1e
#define PHY_DEV1E_REG_13 0x13
#define PHY_DEV1E_REG_14 0x14
#define PHY_DEV1E_REG_41 0x41
#define PHY_DEV1E_REG_A6 0xa6
#define PHY_DEV1E_REG_0C6 0x0c6
#define PHY_DEV1E_REG_0FE 0x0fe
#define PHY_DEV1E_REG_123 0x123
#define PHY_DEV1E_REG_189 0x189
/* Fields of PHY_DEV1E_REG_0C6 */
#define PHY_POWER_SAVING_S 8
#define PHY_POWER_SAVING_M 0x300
#define PHY_POWER_SAVING_TX 0x0
/* Fields of PHY_DEV1E_REG_189 */
#define DESCRAMBLER_CLEAR_EN 0x1
/* Values of XTAL_FSEL_S */
#define XTAL_40MHZ 0
#define XTAL_25MHZ 1
#define PLLGP_EN 0x7820
#define EN_COREPLL BIT(2)
#define SW_CLKSW BIT(1)
#define SW_PLLGP BIT(0)
#define PLLGP_CR0 0x78a8
#define RG_COREPLL_EN BIT(22)
#define RG_COREPLL_POSDIV_S 23
#define RG_COREPLL_POSDIV_M 0x3800000
#define RG_COREPLL_SDM_PCW_S 1
#define RG_COREPLL_SDM_PCW_M 0x3ffffe
#define RG_COREPLL_SDM_PCW_CHG BIT(0)
/* TOP Signals Status Register */
#define TOP_SIG_SR 0x780c
#define PAD_DUAL_SGMII_EN BIT(1)
/* RGMII and SGMII PLL clock */
#define ANA_PLLGP_CR2 0x78b0
#define ANA_PLLGP_CR5 0x78bc
/* GPIO mode define */
#define GPIO_MODE_REGS(x) (0x7c0c + (((x) / 8) * 4))
#define GPIO_MODE_S 4
/* GPIO GROUP IOLB SMT0 Control */
#define SMT0_IOLB 0x7f04
#define SMT_IOLB_5_SMI_MDC_EN BIT(5)
/* Unique fields of PMCR for MT7531 */
#define FORCE_MODE_EEE1G BIT(25)
#define FORCE_MODE_EEE100 BIT(26)
#define FORCE_MODE_TX_FC BIT(27)
#define FORCE_MODE_RX_FC BIT(28)
#define FORCE_MODE_DPX BIT(29)
#define FORCE_MODE_SPD BIT(30)
#define FORCE_MODE_LNK BIT(31)
#define FORCE_MODE BIT(15)
#define CHIP_REV 0x781C
#define CHIP_NAME_S 16
#define CHIP_NAME_M 0xffff0000
#define CHIP_REV_S 0
#define CHIP_REV_M 0x0f
#define CHIP_REV_E1 0x0
#define CLKGEN_CTRL 0x7500
#define CLK_SKEW_OUT_S 8
#define CLK_SKEW_OUT_M 0x300
#define CLK_SKEW_IN_S 6
#define CLK_SKEW_IN_M 0xc0
#define RXCLK_NO_DELAY BIT(5)
#define TXCLK_NO_REVERSE BIT(4)
#define GP_MODE_S 1
#define GP_MODE_M 0x06
#define GP_CLK_EN BIT(0)
/* Values of GP_MODE */
#define GP_MODE_RGMII 0
#define GP_MODE_MII 1
#define GP_MODE_REV_MII 2
/* Values of CLK_SKEW_IN */
#define CLK_SKEW_IN_NO_CHANGE 0
#define CLK_SKEW_IN_DELAY_100PPS 1
#define CLK_SKEW_IN_DELAY_200PPS 2
#define CLK_SKEW_IN_REVERSE 3
/* Values of CLK_SKEW_OUT */
#define CLK_SKEW_OUT_NO_CHANGE 0
#define CLK_SKEW_OUT_DELAY_100PPS 1
#define CLK_SKEW_OUT_DELAY_200PPS 2
#define CLK_SKEW_OUT_REVERSE 3
/* Proprietory Control Register of Internal Phy device 0x1e */
#define RXADC_CONTROL_3 0xc2
#define RXADC_LDO_CONTROL_2 0xd3
/* Proprietory Control Register of Internal Phy device 0x1f */
#define TXVLD_DA_271 0x271
#define TXVLD_DA_272 0x272
#define TXVLD_DA_273 0x273
/* DSP Channel and NOD_ADDR*/
#define DSP_CH 0x2
#define DSP_NOD_ADDR 0xD
/* gpio pinmux pins and functions define */
static int gpio_int_pins[] = {0};
static int gpio_int_funcs[] = {1};
static int gpio_mdc_pins[] = {11, 20};
static int gpio_mdc_funcs[] = {2, 2};
static int gpio_mdio_pins[] = {12, 21};
static int gpio_mdio_funcs[] = {2, 2};
static int mt7531_set_port_sgmii_force_mode(struct gsw_mt753x *gsw, u32 port,
struct mt753x_port_cfg *port_cfg)
{
u32 speed, port_base, val;
ktime_t timeout;
u32 timeout_us;
if (port < 5 || port >= MT753X_NUM_PORTS) {
dev_info(gsw->dev, "port %d is not a SGMII port\n", port);
return -EINVAL;
}
port_base = port - 5;
switch (port_cfg->speed) {
case MAC_SPD_1000:
speed = RG_TPHY_SPEED_1000;
break;
case MAC_SPD_2500:
speed = RG_TPHY_SPEED_2500;
break;
default:
dev_info(gsw->dev, "invalid SGMII speed idx %d for port %d\n",
port_cfg->speed, port);
speed = RG_TPHY_SPEED_1000;
}
/* Step 1: Speed select register setting */
val = mt753x_reg_read(gsw, PHYA_CTRL_SIGNAL3(port_base));
val &= ~RG_TPHY_SPEED_M;
val |= speed << RG_TPHY_SPEED_S;
mt753x_reg_write(gsw, PHYA_CTRL_SIGNAL3(port_base), val);
/* Step 2 : Disable AN */
val = mt753x_reg_read(gsw, PCS_CONTROL_1(port_base));
val &= ~SGMII_AN_ENABLE;
mt753x_reg_write(gsw, PCS_CONTROL_1(port_base), val);
/* Step 3: SGMII force mode setting */
val = mt753x_reg_read(gsw, SGMII_MODE(port_base));
val &= ~SGMII_IF_MODE_ADVERT_AN;
val &= ~SGMII_IF_MODE_FORCE_SPEED_M;
val |= SGMII_IF_MODE_FORCE_SPEED_1000 << SGMII_IF_MODE_FORCE_SPEED_S;
val |= SGMII_IF_MODE_FORCE_DUPLEX;
/* For sgmii force mode, 0 is full duplex and 1 is half duplex */
if (port_cfg->duplex)
val &= ~SGMII_IF_MODE_FORCE_DUPLEX;
mt753x_reg_write(gsw, SGMII_MODE(port_base), val);
/* Step 4: XXX: Disable Link partner's AN and set force mode */
/* Step 5: XXX: Special setting for PHYA ==> reserved for flexible */
/* Step 6 : Release PHYA power down state */
val = mt753x_reg_read(gsw, QPHY_PWR_STATE_CTRL(port_base));
val &= ~PHYA_PWD;
mt753x_reg_write(gsw, QPHY_PWR_STATE_CTRL(port_base), val);
/* Step 7 : Polling SGMII_LINK_STATUS */
timeout_us = 2000000;
timeout = ktime_add_us(ktime_get(), timeout_us);
while (1) {
val = mt753x_reg_read(gsw, PCS_CONTROL_1(port_base));
val &= SGMII_LINK_STATUS;
if (val)
break;
if (ktime_compare(ktime_get(), timeout) > 0)
return -ETIMEDOUT;
}
return 0;
}
static int mt7531_set_port_sgmii_an_mode(struct gsw_mt753x *gsw, u32 port,
struct mt753x_port_cfg *port_cfg)
{
u32 speed, port_base, val;
ktime_t timeout;
u32 timeout_us;
if (port < 5 || port >= MT753X_NUM_PORTS) {
dev_info(gsw->dev, "port %d is not a SGMII port\n", port);
return -EINVAL;
}
port_base = port - 5;
switch (port_cfg->speed) {
case MAC_SPD_1000:
speed = RG_TPHY_SPEED_1000;
break;
case MAC_SPD_2500:
speed = RG_TPHY_SPEED_2500;
break;
default:
dev_info(gsw->dev, "invalid SGMII speed idx %d for port %d\n",
port_cfg->speed, port);
speed = RG_TPHY_SPEED_1000;
}
/* Step 1: Speed select register setting */
val = mt753x_reg_read(gsw, PHYA_CTRL_SIGNAL3(port_base));
val &= ~RG_TPHY_SPEED_M;
val |= speed << RG_TPHY_SPEED_S;
mt753x_reg_write(gsw, PHYA_CTRL_SIGNAL3(port_base), val);
/* Step 2: Remote fault disable */
val = mt753x_reg_read(gsw, SGMII_MODE(port));
val |= SGMII_REMOTE_FAULT_DIS;
mt753x_reg_write(gsw, SGMII_MODE(port), val);
/* Step 3: Setting Link partner's AN enable = 1 */
/* Step 4: Setting Link partner's device ability for speed/duplex */
/* Step 5: AN re-start */
val = mt753x_reg_read(gsw, PCS_CONTROL_1(port));
val |= SGMII_AN_RESTART;
mt753x_reg_write(gsw, PCS_CONTROL_1(port), val);
/* Step 6: Special setting for PHYA ==> reserved for flexible */
/* Step 7 : Polling SGMII_LINK_STATUS */
timeout_us = 2000000;
timeout = ktime_add_us(ktime_get(), timeout_us);
while (1) {
val = mt753x_reg_read(gsw, PCS_CONTROL_1(port_base));
val &= SGMII_LINK_STATUS;
if (val)
break;
if (ktime_compare(ktime_get(), timeout) > 0)
return -ETIMEDOUT;
}
return 0;
}
static int mt7531_set_port_rgmii(struct gsw_mt753x *gsw, u32 port)
{
u32 val;
if (port != 5) {
dev_info(gsw->dev, "RGMII mode is not available for port %d\n",
port);
return -EINVAL;
}
val = mt753x_reg_read(gsw, CLKGEN_CTRL);
val |= GP_CLK_EN;
val &= ~GP_MODE_M;
val |= GP_MODE_RGMII << GP_MODE_S;
val |= TXCLK_NO_REVERSE;
val |= RXCLK_NO_DELAY;
val &= ~CLK_SKEW_IN_M;
val |= CLK_SKEW_IN_NO_CHANGE << CLK_SKEW_IN_S;
val &= ~CLK_SKEW_OUT_M;
val |= CLK_SKEW_OUT_NO_CHANGE << CLK_SKEW_OUT_S;
mt753x_reg_write(gsw, CLKGEN_CTRL, val);
return 0;
}
static int mt7531_mac_port_setup(struct gsw_mt753x *gsw, u32 port,
struct mt753x_port_cfg *port_cfg)
{
u32 pmcr;
u32 speed;
if (port < 5 || port >= MT753X_NUM_PORTS) {
dev_info(gsw->dev, "port %d is not a MAC port\n", port);
return -EINVAL;
}
if (port_cfg->enabled) {
pmcr = (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) |
MAC_MODE | MAC_TX_EN | MAC_RX_EN |
BKOFF_EN | BACKPR_EN;
if (port_cfg->force_link) {
/* PMCR's speed field 0x11 is reserved,
* sw should set 0x10
*/
speed = port_cfg->speed;
if (port_cfg->speed == MAC_SPD_2500)
speed = MAC_SPD_1000;
pmcr |= FORCE_MODE_LNK | FORCE_LINK |
FORCE_MODE_SPD | FORCE_MODE_DPX |
FORCE_MODE_RX_FC | FORCE_MODE_TX_FC |
FORCE_RX_FC | FORCE_TX_FC |
(speed << FORCE_SPD_S);
if (port_cfg->duplex)
pmcr |= FORCE_DPX;
}
} else {
pmcr = FORCE_MODE_LNK;
}
switch (port_cfg->phy_mode) {
case PHY_INTERFACE_MODE_RGMII:
mt7531_set_port_rgmii(gsw, port);
break;
case PHY_INTERFACE_MODE_SGMII:
if (port_cfg->force_link)
mt7531_set_port_sgmii_force_mode(gsw, port, port_cfg);
else
mt7531_set_port_sgmii_an_mode(gsw, port, port_cfg);
break;
default:
if (port_cfg->enabled)
dev_info(gsw->dev, "%s is not supported by port %d\n",
phy_modes(port_cfg->phy_mode), port);
pmcr = FORCE_MODE_LNK;
}
mt753x_reg_write(gsw, PMCR(port), pmcr);
return 0;
}
static void mt7531_core_pll_setup(struct gsw_mt753x *gsw)
{
u32 hwstrap;
u32 val;
val = mt753x_reg_read(gsw, TOP_SIG_SR);
if (val & PAD_DUAL_SGMII_EN)
return;
hwstrap = mt753x_reg_read(gsw, HWSTRAP);
switch ((hwstrap & XTAL_FSEL_M) >> XTAL_FSEL_S) {
case XTAL_25MHZ:
/* Step 1 : Disable MT7531 COREPLL */
val = mt753x_reg_read(gsw, PLLGP_EN);
val &= ~EN_COREPLL;
mt753x_reg_write(gsw, PLLGP_EN, val);
/* Step 2: switch to XTAL output */
val = mt753x_reg_read(gsw, PLLGP_EN);
val |= SW_CLKSW;
mt753x_reg_write(gsw, PLLGP_EN, val);
val = mt753x_reg_read(gsw, PLLGP_CR0);
val &= ~RG_COREPLL_EN;
mt753x_reg_write(gsw, PLLGP_CR0, val);
/* Step 3: disable PLLGP and enable program PLLGP */
val = mt753x_reg_read(gsw, PLLGP_EN);
val |= SW_PLLGP;
mt753x_reg_write(gsw, PLLGP_EN, val);
/* Step 4: program COREPLL output frequency to 500MHz */
val = mt753x_reg_read(gsw, PLLGP_CR0);
val &= ~RG_COREPLL_POSDIV_M;
val |= 2 << RG_COREPLL_POSDIV_S;
mt753x_reg_write(gsw, PLLGP_CR0, val);
usleep_range(25, 35);
val = mt753x_reg_read(gsw, PLLGP_CR0);
val &= ~RG_COREPLL_SDM_PCW_M;
val |= 0x140000 << RG_COREPLL_SDM_PCW_S;
mt753x_reg_write(gsw, PLLGP_CR0, val);
/* Set feedback divide ratio update signal to high */
val = mt753x_reg_read(gsw, PLLGP_CR0);
val |= RG_COREPLL_SDM_PCW_CHG;
mt753x_reg_write(gsw, PLLGP_CR0, val);
/* Wait for at least 16 XTAL clocks */
usleep_range(10, 20);
/* Step 5: set feedback divide ratio update signal to low */
val = mt753x_reg_read(gsw, PLLGP_CR0);
val &= ~RG_COREPLL_SDM_PCW_CHG;
mt753x_reg_write(gsw, PLLGP_CR0, val);
/* Enable 325M clock for SGMII */
mt753x_reg_write(gsw, ANA_PLLGP_CR5, 0xad0000);
/* Enable 250SSC clock for RGMII */
mt753x_reg_write(gsw, ANA_PLLGP_CR2, 0x4f40000);
/* Step 6: Enable MT7531 PLL */
val = mt753x_reg_read(gsw, PLLGP_CR0);
val |= RG_COREPLL_EN;
mt753x_reg_write(gsw, PLLGP_CR0, val);
val = mt753x_reg_read(gsw, PLLGP_EN);
val |= EN_COREPLL;
mt753x_reg_write(gsw, PLLGP_EN, val);
usleep_range(25, 35);
break;
case XTAL_40MHZ:
/* Step 1 : Disable MT7531 COREPLL */
val = mt753x_reg_read(gsw, PLLGP_EN);
val &= ~EN_COREPLL;
mt753x_reg_write(gsw, PLLGP_EN, val);
/* Step 2: switch to XTAL output */
val = mt753x_reg_read(gsw, PLLGP_EN);
val |= SW_CLKSW;
mt753x_reg_write(gsw, PLLGP_EN, val);
val = mt753x_reg_read(gsw, PLLGP_CR0);
val &= ~RG_COREPLL_EN;
mt753x_reg_write(gsw, PLLGP_CR0, val);
/* Step 3: disable PLLGP and enable program PLLGP */
val = mt753x_reg_read(gsw, PLLGP_EN);
val |= SW_PLLGP;
mt753x_reg_write(gsw, PLLGP_EN, val);
/* Step 4: program COREPLL output frequency to 500MHz */
val = mt753x_reg_read(gsw, PLLGP_CR0);
val &= ~RG_COREPLL_POSDIV_M;
val |= 2 << RG_COREPLL_POSDIV_S;
mt753x_reg_write(gsw, PLLGP_CR0, val);
usleep_range(25, 35);
val = mt753x_reg_read(gsw, PLLGP_CR0);
val &= ~RG_COREPLL_SDM_PCW_M;
val |= 0x190000 << RG_COREPLL_SDM_PCW_S;
mt753x_reg_write(gsw, PLLGP_CR0, val);
/* Set feedback divide ratio update signal to high */
val = mt753x_reg_read(gsw, PLLGP_CR0);
val |= RG_COREPLL_SDM_PCW_CHG;
mt753x_reg_write(gsw, PLLGP_CR0, val);
/* Wait for at least 16 XTAL clocks */
usleep_range(10, 20);
/* Step 5: set feedback divide ratio update signal to low */
val = mt753x_reg_read(gsw, PLLGP_CR0);
val &= ~RG_COREPLL_SDM_PCW_CHG;
mt753x_reg_write(gsw, PLLGP_CR0, val);
/* Enable 325M clock for SGMII */
mt753x_reg_write(gsw, ANA_PLLGP_CR5, 0xad0000);
/* Enable 250SSC clock for RGMII */
mt753x_reg_write(gsw, ANA_PLLGP_CR2, 0x4f40000);
/* Step 6: Enable MT7531 PLL */
val = mt753x_reg_read(gsw, PLLGP_CR0);
val |= RG_COREPLL_EN;
mt753x_reg_write(gsw, PLLGP_CR0, val);
val = mt753x_reg_read(gsw, PLLGP_EN);
val |= EN_COREPLL;
mt753x_reg_write(gsw, PLLGP_EN, val);
usleep_range(25, 35);
break;
}
}
static int mt7531_internal_phy_calibration(struct gsw_mt753x *gsw)
{
return 0;
}
static int mt7531_sw_detect(struct gsw_mt753x *gsw, struct chip_rev *crev)
{
u32 rev, topsig;
rev = mt753x_reg_read(gsw, CHIP_REV);
if (((rev & CHIP_NAME_M) >> CHIP_NAME_S) == MT7531) {
if (crev) {
topsig = mt753x_reg_read(gsw, TOP_SIG_SR);
crev->rev = rev & CHIP_REV_M;
crev->name = topsig & PAD_DUAL_SGMII_EN ?
"MT7531AE" : "MT7531BE";
}
return 0;
}
return -ENODEV;
}
static void pinmux_set_mux_7531(struct gsw_mt753x *gsw, u32 pin, u32 mode)
{
u32 val;
val = mt753x_reg_read(gsw, GPIO_MODE_REGS(pin));
val &= ~(0xf << (pin & 7) * GPIO_MODE_S);
val |= mode << (pin & 7) * GPIO_MODE_S;
mt753x_reg_write(gsw, GPIO_MODE_REGS(pin), val);
}
static int mt7531_set_gpio_pinmux(struct gsw_mt753x *gsw)
{
u32 group = 0;
struct device_node *np = gsw->dev->of_node;
/* Set GPIO 0 interrupt mode */
pinmux_set_mux_7531(gsw, gpio_int_pins[0], gpio_int_funcs[0]);
of_property_read_u32(np, "mediatek,mdio_master_pinmux", &group);
/* group = 0: do nothing, 1: 1st group (AE), 2: 2nd group (BE) */
if (group > 0 && group <= 2) {
group--;
pinmux_set_mux_7531(gsw, gpio_mdc_pins[group],
gpio_mdc_funcs[group]);
pinmux_set_mux_7531(gsw, gpio_mdio_pins[group],
gpio_mdio_funcs[group]);
}
return 0;
}
static void mt7531_phy_pll_setup(struct gsw_mt753x *gsw)
{
u32 hwstrap;
u32 val;
hwstrap = mt753x_reg_read(gsw, HWSTRAP);
switch ((hwstrap & XTAL_FSEL_M) >> XTAL_FSEL_S) {
case XTAL_25MHZ:
/* disable pll auto calibration */
gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_104, 0x608);
/* change pll sel */
val = gsw->mmd_read(gsw, 0, PHY_DEV1F,
PHY_DEV1F_REG_403);
val &= ~(PHY_PLL_M);
val |= PHY_PLL_SEL(3);
gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_403, val);
/* set divider ratio */
gsw->mmd_write(gsw, 0, PHY_DEV1F,
PHY_DEV1F_REG_10A, 0x1009);
/* set divider ratio */
gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_10B, 0x7c6);
/* capacitance and resistance adjustment */
gsw->mmd_write(gsw, 0, PHY_DEV1F,
PHY_DEV1F_REG_10C, 0xa8be);
break;
case XTAL_40MHZ:
/* disable pll auto calibration */
gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_104, 0x608);
/* change pll sel */
val = gsw->mmd_read(gsw, 0, PHY_DEV1F,
PHY_DEV1F_REG_403);
val &= ~(PHY_PLL_M);
val |= PHY_PLL_SEL(3);
gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_403, val);
/* set divider ratio */
gsw->mmd_write(gsw, 0, PHY_DEV1F,
PHY_DEV1F_REG_10A, 0x1018);
/* set divider ratio */
gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_10B, 0xc676);
/* capacitance and resistance adjustment */
gsw->mmd_write(gsw, 0, PHY_DEV1F,
PHY_DEV1F_REG_10C, 0xd8be);
break;
}
/* power down pll. additional delay is not required via mdio access */
gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_10D, 0x10);
/* power up pll */
gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_10D, 0x14);
}
static void mt7531_phy_setting(struct gsw_mt753x *gsw)
{
int i;
u32 val;
/* Adjust DAC TX Delay */
gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_44, 0xc0);
for (i = 0; i < MT753X_NUM_PHYS; i++) {
/* Disable EEE */
gsw->mmd_write(gsw, i, PHY_DEV07, PHY_DEV07_REG_03C, 0);
/* Enable HW auto downshift */
gsw->mii_write(gsw, i, 0x1f, 0x1);
val = gsw->mii_read(gsw, i, PHY_EXT_REG_14);
val |= PHY_EN_DOWN_SHFIT;
gsw->mii_write(gsw, i, PHY_EXT_REG_14, val);
/* Increase SlvDPSready time */
gsw->mii_write(gsw, i, 0x1f, 0x52b5);
gsw->mii_write(gsw, i, PHY_TR_REG_10, 0xafae);
gsw->mii_write(gsw, i, PHY_TR_REG_12, 0x2f);
gsw->mii_write(gsw, i, PHY_TR_REG_10, 0x8fae);
gsw->mii_write(gsw, i, 0x1f, 0);
/* Adjust 100_mse_threshold */
gsw->mmd_write(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_123, 0xffff);
/* Disable mcc */
gsw->mmd_write(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_A6, 0x300);
/* PHY link down power saving enable */
val = gsw->mii_read(gsw, i, PHY_EXT_REG_17);
val |= PHY_LINKDOWN_POWER_SAVING_EN;
gsw->mii_write(gsw, i, PHY_EXT_REG_17, val);
val = gsw->mmd_read(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_0C6);
val &= ~PHY_POWER_SAVING_M;
val |= PHY_POWER_SAVING_TX << PHY_POWER_SAVING_S;
gsw->mmd_write(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_0C6, val);
/* Set TX Pair delay selection */
gsw->mmd_write(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_13, 0x404);
gsw->mmd_write(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_14, 0x404);
}
}
static void mt7531_adjust_line_driving(struct gsw_mt753x *gsw, u32 port)
{
/* For ADC timing margin window for LDO calibration */
gsw->mmd_write(gsw, port, PHY_DEV1E, RXADC_LDO_CONTROL_2, 0x2222);
/* Adjust AD sample timing */
gsw->mmd_write(gsw, port, PHY_DEV1E, RXADC_CONTROL_3, 0x4444);
/* Adjust Line driver current for different mode */
gsw->mmd_write(gsw, port, PHY_DEV1F, TXVLD_DA_271, 0x2ca5);
/* Adjust Line driver current for different mode */
gsw->mmd_write(gsw, port, PHY_DEV1F, TXVLD_DA_272, 0xc6b);
/* Adjust Line driver amplitude for 10BT */
gsw->mmd_write(gsw, port, PHY_DEV1F, TXVLD_DA_273, 0x3000);
/* Adjust RX Echo path filter */
gsw->mmd_write(gsw, port, PHY_DEV1E, PHY_DEV1E_REG_0FE, 0x2);
/* Adjust RX HVGA bias current */
gsw->mmd_write(gsw, port, PHY_DEV1E, PHY_DEV1E_REG_41, 0x3333);
/* Adjust TX class AB driver 1 */
gsw->mmd_write(gsw, port, PHY_DEV1F, PHY_DEV1F_REG_268, 0x388);
/* Adjust TX class AB driver 2 */
gsw->mmd_write(gsw, port, PHY_DEV1F, PHY_DEV1F_REG_269, 0x4448);
}
static void mt7531_eee_setting(struct gsw_mt753x *gsw, u32 port)
{
u32 tr_reg_control;
u32 val;
/* Disable generate signal to clear the scramble_lock when lpi mode */
val = gsw->mmd_read(gsw, port, PHY_DEV1E, PHY_DEV1E_REG_189);
val &= ~DESCRAMBLER_CLEAR_EN;
gsw->mmd_write(gsw, port, PHY_DEV1E, PHY_DEV1E_REG_189, val);
/* roll back CR*/
gsw->mii_write(gsw, port, 0x1f, 0x52b5);
gsw->mmd_write(gsw, port, 0x1e, 0x2d1, 0);
tr_reg_control = (1 << 15) | (0 << 13) | (DSP_CH << 11) |
(DSP_NOD_ADDR << 7) | (0x8 << 1);
gsw->mii_write(gsw, port, 17, 0x1b);
gsw->mii_write(gsw, port, 18, 0);
gsw->mii_write(gsw, port, 16, tr_reg_control);
tr_reg_control = (1 << 15) | (0 << 13) | (DSP_CH << 11) |
(DSP_NOD_ADDR << 7) | (0xf << 1);
gsw->mii_write(gsw, port, 17, 0);
gsw->mii_write(gsw, port, 18, 0);
gsw->mii_write(gsw, port, 16, tr_reg_control);
tr_reg_control = (1 << 15) | (0 << 13) | (DSP_CH << 11) |
(DSP_NOD_ADDR << 7) | (0x10 << 1);
gsw->mii_write(gsw, port, 17, 0x500);
gsw->mii_write(gsw, port, 18, 0);
gsw->mii_write(gsw, port, 16, tr_reg_control);
gsw->mii_write(gsw, port, 0x1f, 0);
}
static int mt7531_sw_init(struct gsw_mt753x *gsw)
{
int i;
u32 val;
gsw->phy_base = (gsw->smi_addr + 1) & MT753X_SMI_ADDR_MASK;
gsw->mii_read = mt753x_mii_read;
gsw->mii_write = mt753x_mii_write;
gsw->mmd_read = mt753x_mmd_read;
gsw->mmd_write = mt753x_mmd_write;
for (i = 0; i < MT753X_NUM_PHYS; i++) {
val = gsw->mii_read(gsw, i, MII_BMCR);
val |= BMCR_ISOLATE;
gsw->mii_write(gsw, i, MII_BMCR, val);
}
/* Force MAC link down before reset */
mt753x_reg_write(gsw, PMCR(5), FORCE_MODE_LNK);
mt753x_reg_write(gsw, PMCR(6), FORCE_MODE_LNK);
/* Switch soft reset */
mt753x_reg_write(gsw, SYS_CTRL, SW_SYS_RST | SW_REG_RST);
usleep_range(10, 20);
/* Enable MDC input Schmitt Trigger */
val = mt753x_reg_read(gsw, SMT0_IOLB);
mt753x_reg_write(gsw, SMT0_IOLB, val | SMT_IOLB_5_SMI_MDC_EN);
/* Set 7531 gpio pinmux */
mt7531_set_gpio_pinmux(gsw);
/* Global mac control settings */
mt753x_reg_write(gsw, GMACCR,
(15 << MTCC_LMT_S) | (11 << MAX_RX_JUMBO_S) |
RX_PKT_LEN_MAX_JUMBO);
mt7531_core_pll_setup(gsw);
mt7531_mac_port_setup(gsw, 5, &gsw->port5_cfg);
mt7531_mac_port_setup(gsw, 6, &gsw->port6_cfg);
return 0;
}
static int mt7531_sw_post_init(struct gsw_mt753x *gsw)
{
int i;
u32 val;
mt7531_phy_pll_setup(gsw);
/* Internal PHYs are disabled by default. SW should enable them.
* Note that this may already be enabled in bootloader stage.
*/
val = gsw->mmd_read(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_403);
val |= PHY_EN_BYPASS_MODE;
val &= ~POWER_ON_OFF;
gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_403, val);
mt7531_phy_setting(gsw);
for (i = 0; i < MT753X_NUM_PHYS; i++) {
val = gsw->mii_read(gsw, i, MII_BMCR);
val &= ~BMCR_ISOLATE;
gsw->mii_write(gsw, i, MII_BMCR, val);
}
for (i = 0; i < MT753X_NUM_PHYS; i++)
mt7531_adjust_line_driving(gsw, i);
for (i = 0; i < MT753X_NUM_PHYS; i++)
mt7531_eee_setting(gsw, i);
val = mt753x_reg_read(gsw, CHIP_REV);
val &= CHIP_REV_M;
if (val == CHIP_REV_E1) {
mt7531_internal_phy_calibration(gsw);
} else {
val = mt753x_reg_read(gsw, GBE_EFUSE);
if (val & GBE_SEL_EFUSE_EN) {
val = gsw->mmd_read(gsw, 0, PHY_DEV1F,
PHY_DEV1F_REG_403);
val &= ~GBE_EFUSE_SETTING;
gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_403,
val);
} else {
mt7531_internal_phy_calibration(gsw);
}
}
return 0;
}
struct mt753x_sw_id mt7531_id = {
.model = MT7531,
.detect = mt7531_sw_detect,
.init = mt7531_sw_init,
.post_init = mt7531_sw_post_init
};
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Zhanguo Ju <zhanguo.ju@mediatek.com>");
MODULE_DESCRIPTION("Driver for MediaTek MT753x Gigabit Switch");

View file

@ -0,0 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018 MediaTek Inc.
*/
#ifndef _MT7531_H_
#define _MT7531_H_
#include "mt753x.h"
extern struct mt753x_sw_id mt7531_id;
#endif /* _MT7531_H_ */

View file

@ -0,0 +1,213 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018 MediaTek Inc.
* Author: Weijie Gao <weijie.gao@mediatek.com>
*/
#ifndef _MT753X_H_
#define _MT753X_H_
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/netdevice.h>
#include <linux/of_mdio.h>
#include <linux/workqueue.h>
#include <linux/gpio/consumer.h>
#ifdef CONFIG_SWCONFIG
#include <linux/switch.h>
#endif
#include "mt753x_vlan.h"
#define MT753X_DFL_CPU_PORT 6
#define MT753X_NUM_PHYS 5
#define MT753X_DFL_SMI_ADDR 0x1f
#define MT753X_SMI_ADDR_MASK 0x1f
struct gsw_mt753x;
enum mt753x_model {
MT7530 = 0x7530,
MT7531 = 0x7531
};
struct mt753x_port_cfg {
struct device_node *np;
phy_interface_t phy_mode;
u32 enabled: 1;
u32 force_link: 1;
u32 speed: 2;
u32 duplex: 1;
};
struct mt753x_phy {
struct gsw_mt753x *gsw;
struct net_device netdev;
struct phy_device *phydev;
};
struct gsw_mt753x {
u32 id;
struct device *dev;
struct mii_bus *host_bus;
struct mii_bus *gphy_bus;
struct mutex mii_lock; /* MII access lock */
u32 smi_addr;
u32 phy_base;
int direct_phy_access;
enum mt753x_model model;
const char *name;
struct mt753x_port_cfg port5_cfg;
struct mt753x_port_cfg port6_cfg;
int phy_status_poll;
struct mt753x_phy phys[MT753X_NUM_PHYS];
int phy_link_sts;
int irq;
int reset_pin;
struct work_struct irq_worker;
#ifdef CONFIG_SWCONFIG
struct switch_dev swdev;
u32 cpu_port;
#endif
int global_vlan_enable;
struct mt753x_vlan_entry vlan_entries[MT753X_NUM_VLANS];
struct mt753x_port_entry port_entries[MT753X_NUM_PORTS];
int (*mii_read)(struct gsw_mt753x *gsw, int phy, int reg);
void (*mii_write)(struct gsw_mt753x *gsw, int phy, int reg, u16 val);
int (*mmd_read)(struct gsw_mt753x *gsw, int addr, int devad, u16 reg);
void (*mmd_write)(struct gsw_mt753x *gsw, int addr, int devad, u16 reg,
u16 val);
struct list_head list;
};
struct chip_rev {
const char *name;
u32 rev;
};
struct mt753x_sw_id {
enum mt753x_model model;
int (*detect)(struct gsw_mt753x *gsw, struct chip_rev *crev);
int (*init)(struct gsw_mt753x *gsw);
int (*post_init)(struct gsw_mt753x *gsw);
};
extern struct list_head mt753x_devs;
struct gsw_mt753x *mt753x_get_gsw(u32 id);
struct gsw_mt753x *mt753x_get_first_gsw(void);
void mt753x_put_gsw(void);
void mt753x_lock_gsw(void);
u32 mt753x_reg_read(struct gsw_mt753x *gsw, u32 reg);
void mt753x_reg_write(struct gsw_mt753x *gsw, u32 reg, u32 val);
int mt753x_mii_read(struct gsw_mt753x *gsw, int phy, int reg);
void mt753x_mii_write(struct gsw_mt753x *gsw, int phy, int reg, u16 val);
int mt753x_mmd_read(struct gsw_mt753x *gsw, int addr, int devad, u16 reg);
void mt753x_mmd_write(struct gsw_mt753x *gsw, int addr, int devad, u16 reg,
u16 val);
int mt753x_mmd_ind_read(struct gsw_mt753x *gsw, int addr, int devad, u16 reg);
void mt753x_mmd_ind_write(struct gsw_mt753x *gsw, int addr, int devad, u16 reg,
u16 val);
void mt753x_irq_worker(struct work_struct *work);
void mt753x_irq_enable(struct gsw_mt753x *gsw);
/* MDIO Indirect Access Registers */
#define MII_MMD_ACC_CTL_REG 0x0d
#define MMD_CMD_S 14
#define MMD_CMD_M 0xc000
#define MMD_DEVAD_S 0
#define MMD_DEVAD_M 0x1f
/* MMD_CMD: MMD commands */
#define MMD_ADDR 0
#define MMD_DATA 1
#define MII_MMD_ADDR_DATA_REG 0x0e
/* Procedure of MT753x Internal Register Access
*
* 1. Internal Register Address
*
* The MT753x has a 16-bit register address and each register is 32-bit.
* This means the lowest two bits are not used as the register address is
* 4-byte aligned.
*
* Rest of the valid bits are divided into two parts:
* Bit 15..6 is the Page address
* Bit 5..2 is the low address
*
* -------------------------------------------------------------------
* | 15 14 13 12 11 10 9 8 7 6 | 5 4 3 2 | 1 0 |
* |----------------------------------------|---------------|--------|
* | Page Address | Address | Unused |
* -------------------------------------------------------------------
*
* 2. MDIO access timing
*
* The MT753x uses the following MDIO timing for a single register read
*
* Phase 1: Write Page Address
* -------------------------------------------------------------------
* | ST | OP | PHY_ADDR | TYPE | RSVD | TA | RSVD | PAGE_ADDR |
* -------------------------------------------------------------------
* | 01 | 01 | 11111 | 1 | 1111 | xx | 00000 | REG_ADDR[15..6] |
* -------------------------------------------------------------------
*
* Phase 2: Write low Address & Read low word
* -------------------------------------------------------------------
* | ST | OP | PHY_ADDR | TYPE | LOW_ADDR | TA | DATA |
* -------------------------------------------------------------------
* | 01 | 10 | 11111 | 0 | REG_ADDR[5..2] | xx | DATA[15..0] |
* -------------------------------------------------------------------
*
* Phase 3: Read high word
* -------------------------------------------------------------------
* | ST | OP | PHY_ADDR | TYPE | RSVD | TA | DATA |
* -------------------------------------------------------------------
* | 01 | 10 | 11111 | 1 | 0000 | xx | DATA[31..16] |
* -------------------------------------------------------------------
*
* The MT753x uses the following MDIO timing for a single register write
*
* Phase 1: Write Page Address (The same as read)
*
* Phase 2: Write low Address and low word
* -------------------------------------------------------------------
* | ST | OP | PHY_ADDR | TYPE | LOW_ADDR | TA | DATA |
* -------------------------------------------------------------------
* | 01 | 01 | 11111 | 0 | REG_ADDR[5..2] | xx | DATA[15..0] |
* -------------------------------------------------------------------
*
* Phase 3: write high word
* -------------------------------------------------------------------
* | ST | OP | PHY_ADDR | TYPE | RSVD | TA | DATA |
* -------------------------------------------------------------------
* | 01 | 01 | 11111 | 1 | 0000 | xx | DATA[31..16] |
* -------------------------------------------------------------------
*
*/
/* Internal Register Address fields */
#define MT753X_REG_PAGE_ADDR_S 6
#define MT753X_REG_PAGE_ADDR_M 0xffc0
#define MT753X_REG_ADDR_S 2
#define MT753X_REG_ADDR_M 0x3c
#endif /* _MT753X_H_ */

View file

@ -0,0 +1,90 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018 MediaTek Inc.
* Author: Weijie Gao <weijie.gao@mediatek.com>
*/
#include <linux/kernel.h>
#include <linux/delay.h>
#include "mt753x.h"
#include "mt753x_regs.h"
void mt753x_irq_enable(struct gsw_mt753x *gsw)
{
u32 val;
int i;
/* Record initial PHY link status */
for (i = 0; i < MT753X_NUM_PHYS; i++) {
val = gsw->mii_read(gsw, i, MII_BMSR);
if (val & BMSR_LSTATUS)
gsw->phy_link_sts |= BIT(i);
}
val = BIT(MT753X_NUM_PHYS) - 1;
mt753x_reg_write(gsw, SYS_INT_EN, val);
}
static void display_port_link_status(struct gsw_mt753x *gsw, u32 port)
{
u32 pmsr, speed_bits;
const char *speed;
pmsr = mt753x_reg_read(gsw, PMSR(port));
speed_bits = (pmsr & MAC_SPD_STS_M) >> MAC_SPD_STS_S;
switch (speed_bits) {
case MAC_SPD_10:
speed = "10Mbps";
break;
case MAC_SPD_100:
speed = "100Mbps";
break;
case MAC_SPD_1000:
speed = "1Gbps";
break;
case MAC_SPD_2500:
speed = "2.5Gbps";
break;
}
if (pmsr & MAC_LNK_STS) {
dev_info(gsw->dev, "Port %d Link is Up - %s/%s\n",
port, speed, (pmsr & MAC_DPX_STS) ? "Full" : "Half");
} else {
dev_info(gsw->dev, "Port %d Link is Down\n", port);
}
}
void mt753x_irq_worker(struct work_struct *work)
{
struct gsw_mt753x *gsw;
u32 sts, physts, laststs;
int i;
gsw = container_of(work, struct gsw_mt753x, irq_worker);
sts = mt753x_reg_read(gsw, SYS_INT_STS);
/* Check for changed PHY link status */
for (i = 0; i < MT753X_NUM_PHYS; i++) {
if (!(sts & PHY_LC_INT(i)))
continue;
laststs = gsw->phy_link_sts & BIT(i);
physts = !!(gsw->mii_read(gsw, i, MII_BMSR) & BMSR_LSTATUS);
physts <<= i;
if (physts ^ laststs) {
gsw->phy_link_sts ^= BIT(i);
display_port_link_status(gsw, i);
}
}
mt753x_reg_write(gsw, SYS_INT_STS, sts);
enable_irq(gsw->irq);
}

View file

@ -0,0 +1,597 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018 MediaTek Inc.
* Author: Weijie Gao <weijie.gao@mediatek.com>
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/reset.h>
#include <linux/hrtimer.h>
#include <linux/mii.h>
#include <linux/of_mdio.h>
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
#include <linux/of_net.h>
#include <linux/of_irq.h>
#include <linux/phy.h>
#include "mt753x.h"
#include "mt753x_swconfig.h"
#include "mt753x_regs.h"
#include "mt753x_nl.h"
#include "mt7530.h"
#include "mt7531.h"
static u32 mt753x_id;
struct list_head mt753x_devs;
static DEFINE_MUTEX(mt753x_devs_lock);
static struct mt753x_sw_id *mt753x_sw_ids[] = {
&mt7530_id,
&mt7531_id,
};
u32 mt753x_reg_read(struct gsw_mt753x *gsw, u32 reg)
{
u32 high, low;
mutex_lock(&gsw->host_bus->mdio_lock);
gsw->host_bus->write(gsw->host_bus, gsw->smi_addr, 0x1f,
(reg & MT753X_REG_PAGE_ADDR_M) >> MT753X_REG_PAGE_ADDR_S);
low = gsw->host_bus->read(gsw->host_bus, gsw->smi_addr,
(reg & MT753X_REG_ADDR_M) >> MT753X_REG_ADDR_S);
high = gsw->host_bus->read(gsw->host_bus, gsw->smi_addr, 0x10);
mutex_unlock(&gsw->host_bus->mdio_lock);
return (high << 16) | (low & 0xffff);
}
void mt753x_reg_write(struct gsw_mt753x *gsw, u32 reg, u32 val)
{
mutex_lock(&gsw->host_bus->mdio_lock);
gsw->host_bus->write(gsw->host_bus, gsw->smi_addr, 0x1f,
(reg & MT753X_REG_PAGE_ADDR_M) >> MT753X_REG_PAGE_ADDR_S);
gsw->host_bus->write(gsw->host_bus, gsw->smi_addr,
(reg & MT753X_REG_ADDR_M) >> MT753X_REG_ADDR_S, val & 0xffff);
gsw->host_bus->write(gsw->host_bus, gsw->smi_addr, 0x10, val >> 16);
mutex_unlock(&gsw->host_bus->mdio_lock);
}
/* Indirect MDIO clause 22/45 access */
static int mt753x_mii_rw(struct gsw_mt753x *gsw, int phy, int reg, u16 data,
u32 cmd, u32 st)
{
ktime_t timeout;
u32 val, timeout_us;
int ret = 0;
timeout_us = 100000;
timeout = ktime_add_us(ktime_get(), timeout_us);
while (1) {
val = mt753x_reg_read(gsw, PHY_IAC);
if ((val & PHY_ACS_ST) == 0)
break;
if (ktime_compare(ktime_get(), timeout) > 0)
return -ETIMEDOUT;
}
val = (st << MDIO_ST_S) |
((cmd << MDIO_CMD_S) & MDIO_CMD_M) |
((phy << MDIO_PHY_ADDR_S) & MDIO_PHY_ADDR_M) |
((reg << MDIO_REG_ADDR_S) & MDIO_REG_ADDR_M);
if (cmd == MDIO_CMD_WRITE || cmd == MDIO_CMD_ADDR)
val |= data & MDIO_RW_DATA_M;
mt753x_reg_write(gsw, PHY_IAC, val | PHY_ACS_ST);
timeout_us = 100000;
timeout = ktime_add_us(ktime_get(), timeout_us);
while (1) {
val = mt753x_reg_read(gsw, PHY_IAC);
if ((val & PHY_ACS_ST) == 0)
break;
if (ktime_compare(ktime_get(), timeout) > 0)
return -ETIMEDOUT;
}
if (cmd == MDIO_CMD_READ || cmd == MDIO_CMD_READ_C45) {
val = mt753x_reg_read(gsw, PHY_IAC);
ret = val & MDIO_RW_DATA_M;
}
return ret;
}
int mt753x_mii_read(struct gsw_mt753x *gsw, int phy, int reg)
{
int val;
if (phy < MT753X_NUM_PHYS)
phy = (gsw->phy_base + phy) & MT753X_SMI_ADDR_MASK;
mutex_lock(&gsw->mii_lock);
val = mt753x_mii_rw(gsw, phy, reg, 0, MDIO_CMD_READ, MDIO_ST_C22);
mutex_unlock(&gsw->mii_lock);
return val;
}
void mt753x_mii_write(struct gsw_mt753x *gsw, int phy, int reg, u16 val)
{
if (phy < MT753X_NUM_PHYS)
phy = (gsw->phy_base + phy) & MT753X_SMI_ADDR_MASK;
mutex_lock(&gsw->mii_lock);
mt753x_mii_rw(gsw, phy, reg, val, MDIO_CMD_WRITE, MDIO_ST_C22);
mutex_unlock(&gsw->mii_lock);
}
int mt753x_mmd_read(struct gsw_mt753x *gsw, int addr, int devad, u16 reg)
{
int val;
if (addr < MT753X_NUM_PHYS)
addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK;
mutex_lock(&gsw->mii_lock);
mt753x_mii_rw(gsw, addr, devad, reg, MDIO_CMD_ADDR, MDIO_ST_C45);
val = mt753x_mii_rw(gsw, addr, devad, 0, MDIO_CMD_READ_C45,
MDIO_ST_C45);
mutex_unlock(&gsw->mii_lock);
return val;
}
void mt753x_mmd_write(struct gsw_mt753x *gsw, int addr, int devad, u16 reg,
u16 val)
{
if (addr < MT753X_NUM_PHYS)
addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK;
mutex_lock(&gsw->mii_lock);
mt753x_mii_rw(gsw, addr, devad, reg, MDIO_CMD_ADDR, MDIO_ST_C45);
mt753x_mii_rw(gsw, addr, devad, val, MDIO_CMD_WRITE, MDIO_ST_C45);
mutex_unlock(&gsw->mii_lock);
}
int mt753x_mmd_ind_read(struct gsw_mt753x *gsw, int addr, int devad, u16 reg)
{
u16 val;
if (addr < MT753X_NUM_PHYS)
addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK;
mutex_lock(&gsw->mii_lock);
mt753x_mii_rw(gsw, addr, MII_MMD_ACC_CTL_REG,
(MMD_ADDR << MMD_CMD_S) |
((devad << MMD_DEVAD_S) & MMD_DEVAD_M),
MDIO_CMD_WRITE, MDIO_ST_C22);
mt753x_mii_rw(gsw, addr, MII_MMD_ADDR_DATA_REG, reg,
MDIO_CMD_WRITE, MDIO_ST_C22);
mt753x_mii_rw(gsw, addr, MII_MMD_ACC_CTL_REG,
(MMD_DATA << MMD_CMD_S) |
((devad << MMD_DEVAD_S) & MMD_DEVAD_M),
MDIO_CMD_WRITE, MDIO_ST_C22);
val = mt753x_mii_rw(gsw, addr, MII_MMD_ADDR_DATA_REG, 0,
MDIO_CMD_READ, MDIO_ST_C22);
mutex_unlock(&gsw->mii_lock);
return val;
}
void mt753x_mmd_ind_write(struct gsw_mt753x *gsw, int addr, int devad, u16 reg,
u16 val)
{
if (addr < MT753X_NUM_PHYS)
addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK;
mutex_lock(&gsw->mii_lock);
mt753x_mii_rw(gsw, addr, MII_MMD_ACC_CTL_REG,
(MMD_ADDR << MMD_CMD_S) |
((devad << MMD_DEVAD_S) & MMD_DEVAD_M),
MDIO_CMD_WRITE, MDIO_ST_C22);
mt753x_mii_rw(gsw, addr, MII_MMD_ADDR_DATA_REG, reg,
MDIO_CMD_WRITE, MDIO_ST_C22);
mt753x_mii_rw(gsw, addr, MII_MMD_ACC_CTL_REG,
(MMD_DATA << MMD_CMD_S) |
((devad << MMD_DEVAD_S) & MMD_DEVAD_M),
MDIO_CMD_WRITE, MDIO_ST_C22);
mt753x_mii_rw(gsw, addr, MII_MMD_ADDR_DATA_REG, val,
MDIO_CMD_WRITE, MDIO_ST_C22);
mutex_unlock(&gsw->mii_lock);
}
static inline int mt753x_get_duplex(const struct device_node *np)
{
return of_property_read_bool(np, "full-duplex");
}
static void mt753x_load_port_cfg(struct gsw_mt753x *gsw)
{
struct device_node *port_np;
struct device_node *fixed_link_node;
struct mt753x_port_cfg *port_cfg;
u32 port;
for_each_child_of_node(gsw->dev->of_node, port_np) {
if (!of_device_is_compatible(port_np, "mediatek,mt753x-port"))
continue;
if (!of_device_is_available(port_np))
continue;
if (of_property_read_u32(port_np, "reg", &port))
continue;
switch (port) {
case 5:
port_cfg = &gsw->port5_cfg;
break;
case 6:
port_cfg = &gsw->port6_cfg;
break;
default:
continue;
}
if (port_cfg->enabled) {
dev_info(gsw->dev, "duplicated node for port%d\n",
port_cfg->phy_mode);
continue;
}
port_cfg->np = port_np;
if (of_get_phy_mode(port_np, &port_cfg->phy_mode) < 0) {
dev_info(gsw->dev, "incorrect phy-mode %d\n", port);
continue;
}
fixed_link_node = of_get_child_by_name(port_np, "fixed-link");
if (fixed_link_node) {
u32 speed;
port_cfg->force_link = 1;
port_cfg->duplex = mt753x_get_duplex(fixed_link_node);
if (of_property_read_u32(fixed_link_node, "speed",
&speed)) {
speed = 0;
continue;
}
of_node_put(fixed_link_node);
switch (speed) {
case 10:
port_cfg->speed = MAC_SPD_10;
break;
case 100:
port_cfg->speed = MAC_SPD_100;
break;
case 1000:
port_cfg->speed = MAC_SPD_1000;
break;
case 2500:
port_cfg->speed = MAC_SPD_2500;
break;
default:
dev_info(gsw->dev, "incorrect speed %d\n",
speed);
continue;
}
}
port_cfg->enabled = 1;
}
}
static void mt753x_add_gsw(struct gsw_mt753x *gsw)
{
mutex_lock(&mt753x_devs_lock);
gsw->id = mt753x_id++;
INIT_LIST_HEAD(&gsw->list);
list_add_tail(&gsw->list, &mt753x_devs);
mutex_unlock(&mt753x_devs_lock);
}
static void mt753x_remove_gsw(struct gsw_mt753x *gsw)
{
mutex_lock(&mt753x_devs_lock);
list_del(&gsw->list);
mutex_unlock(&mt753x_devs_lock);
}
struct gsw_mt753x *mt753x_get_gsw(u32 id)
{
struct gsw_mt753x *dev;
mutex_lock(&mt753x_devs_lock);
list_for_each_entry(dev, &mt753x_devs, list) {
if (dev->id == id)
return dev;
}
mutex_unlock(&mt753x_devs_lock);
return NULL;
}
struct gsw_mt753x *mt753x_get_first_gsw(void)
{
struct gsw_mt753x *dev;
mutex_lock(&mt753x_devs_lock);
list_for_each_entry(dev, &mt753x_devs, list)
return dev;
mutex_unlock(&mt753x_devs_lock);
return NULL;
}
void mt753x_put_gsw(void)
{
mutex_unlock(&mt753x_devs_lock);
}
void mt753x_lock_gsw(void)
{
mutex_lock(&mt753x_devs_lock);
}
static int mt753x_hw_reset(struct gsw_mt753x *gsw)
{
struct device_node *np = gsw->dev->of_node;
struct reset_control *rstc;
int mcm;
int ret = -EINVAL;
mcm = of_property_read_bool(np, "mediatek,mcm");
if (mcm) {
rstc = devm_reset_control_get(gsw->dev, "mcm");
ret = IS_ERR(rstc);
if (IS_ERR(rstc)) {
dev_err(gsw->dev, "Missing reset ctrl of switch\n");
return ret;
}
reset_control_assert(rstc);
msleep(30);
reset_control_deassert(rstc);
gsw->reset_pin = -1;
return 0;
}
gsw->reset_pin = of_get_named_gpio(np, "reset-gpios", 0);
if (gsw->reset_pin < 0) {
dev_err(gsw->dev, "Missing reset pin of switch\n");
return ret;
}
ret = devm_gpio_request(gsw->dev, gsw->reset_pin, "mt753x-reset");
if (ret) {
dev_info(gsw->dev, "Failed to request gpio %d\n",
gsw->reset_pin);
return ret;
}
gpio_direction_output(gsw->reset_pin, 0);
msleep(30);
gpio_set_value(gsw->reset_pin, 1);
msleep(500);
return 0;
}
static irqreturn_t mt753x_irq_handler(int irq, void *dev)
{
struct gsw_mt753x *gsw = dev;
disable_irq_nosync(gsw->irq);
schedule_work(&gsw->irq_worker);
return IRQ_HANDLED;
}
static int mt753x_probe(struct platform_device *pdev)
{
struct gsw_mt753x *gsw;
struct mt753x_sw_id *sw;
struct device_node *np = pdev->dev.of_node;
struct device_node *mdio;
struct mii_bus *mdio_bus;
int ret = -EINVAL;
struct chip_rev rev;
struct mt753x_mapping *map;
int i;
mdio = of_parse_phandle(np, "mediatek,mdio", 0);
if (!mdio)
return -EINVAL;
mdio_bus = of_mdio_find_bus(mdio);
if (!mdio_bus)
return -EPROBE_DEFER;
gsw = devm_kzalloc(&pdev->dev, sizeof(struct gsw_mt753x), GFP_KERNEL);
if (!gsw)
return -ENOMEM;
gsw->host_bus = mdio_bus;
gsw->dev = &pdev->dev;
mutex_init(&gsw->mii_lock);
/* Switch hard reset */
if (mt753x_hw_reset(gsw))
goto fail;
/* Fetch the SMI address dirst */
if (of_property_read_u32(np, "mediatek,smi-addr", &gsw->smi_addr))
gsw->smi_addr = MT753X_DFL_SMI_ADDR;
/* Get LAN/WAN port mapping */
map = mt753x_find_mapping(np);
if (map) {
mt753x_apply_mapping(gsw, map);
gsw->global_vlan_enable = 1;
dev_info(gsw->dev, "LAN/WAN VLAN setting=%s\n", map->name);
}
/* Load MAC port configurations */
mt753x_load_port_cfg(gsw);
/* Check for valid switch and then initialize */
for (i = 0; i < ARRAY_SIZE(mt753x_sw_ids); i++) {
if (!mt753x_sw_ids[i]->detect(gsw, &rev)) {
sw = mt753x_sw_ids[i];
gsw->name = rev.name;
gsw->model = sw->model;
dev_info(gsw->dev, "Switch is MediaTek %s rev %d",
gsw->name, rev.rev);
/* Initialize the switch */
ret = sw->init(gsw);
if (ret)
goto fail;
break;
}
}
if (i >= ARRAY_SIZE(mt753x_sw_ids)) {
dev_err(gsw->dev, "No mt753x switch found\n");
goto fail;
}
gsw->irq = platform_get_irq(pdev, 0);
if (gsw->irq >= 0) {
ret = devm_request_irq(gsw->dev, gsw->irq, mt753x_irq_handler,
0, dev_name(gsw->dev), gsw);
if (ret) {
dev_err(gsw->dev, "Failed to request irq %d\n",
gsw->irq);
goto fail;
}
INIT_WORK(&gsw->irq_worker, mt753x_irq_worker);
}
platform_set_drvdata(pdev, gsw);
gsw->phy_status_poll = of_property_read_bool(gsw->dev->of_node,
"mediatek,phy-poll");
mt753x_add_gsw(gsw);
mt753x_swconfig_init(gsw);
if (sw->post_init)
sw->post_init(gsw);
if (gsw->irq >= 0)
mt753x_irq_enable(gsw);
return 0;
fail:
devm_kfree(&pdev->dev, gsw);
return ret;
}
static int mt753x_remove(struct platform_device *pdev)
{
struct gsw_mt753x *gsw = platform_get_drvdata(pdev);
if (gsw->irq >= 0)
cancel_work_sync(&gsw->irq_worker);
if (gsw->reset_pin >= 0)
devm_gpio_free(&pdev->dev, gsw->reset_pin);
#ifdef CONFIG_SWCONFIG
mt753x_swconfig_destroy(gsw);
#endif
mt753x_remove_gsw(gsw);
platform_set_drvdata(pdev, NULL);
return 0;
}
static const struct of_device_id mt753x_ids[] = {
{ .compatible = "mediatek,mt753x" },
{ },
};
MODULE_DEVICE_TABLE(of, mt753x_ids);
static struct platform_driver mt753x_driver = {
.probe = mt753x_probe,
.remove = mt753x_remove,
.driver = {
.name = "mt753x",
.of_match_table = mt753x_ids,
},
};
static int __init mt753x_init(void)
{
int ret;
INIT_LIST_HEAD(&mt753x_devs);
ret = platform_driver_register(&mt753x_driver);
mt753x_nl_init();
return ret;
}
module_init(mt753x_init);
static void __exit mt753x_exit(void)
{
mt753x_nl_exit();
platform_driver_unregister(&mt753x_driver);
}
module_exit(mt753x_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Weijie Gao <weijie.gao@mediatek.com>");
MODULE_DESCRIPTION("Driver for MediaTek MT753x Gigabit Switch");

View file

@ -0,0 +1,382 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018 MediaTek Inc.
* Author: Sirui Zhao <Sirui.Zhao@mediatek.com>
*/
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <net/genetlink.h>
#include "mt753x.h"
#include "mt753x_nl.h"
struct mt753x_nl_cmd_item {
enum mt753x_cmd cmd;
bool require_dev;
int (*process)(struct genl_info *info, struct gsw_mt753x *gsw);
u32 nr_required_attrs;
const enum mt753x_attr *required_attrs;
};
static int mt753x_nl_response(struct sk_buff *skb, struct genl_info *info);
/*
static const struct nla_policy mt753x_nl_cmd_policy[] = {
[MT753X_ATTR_TYPE_MESG] = { .type = NLA_STRING },
[MT753X_ATTR_TYPE_PHY] = { .type = NLA_S32 },
[MT753X_ATTR_TYPE_REG] = { .type = NLA_S32 },
[MT753X_ATTR_TYPE_VAL] = { .type = NLA_S32 },
[MT753X_ATTR_TYPE_DEV_NAME] = { .type = NLA_S32 },
[MT753X_ATTR_TYPE_DEV_ID] = { .type = NLA_S32 },
[MT753X_ATTR_TYPE_DEVAD] = { .type = NLA_S32 },
};
*/
static const struct genl_ops mt753x_nl_ops[] = {
{
.cmd = MT753X_CMD_REQUEST,
.doit = mt753x_nl_response,
// .policy = mt753x_nl_cmd_policy,
.flags = GENL_ADMIN_PERM,
}, {
.cmd = MT753X_CMD_READ,
.doit = mt753x_nl_response,
// .policy = mt753x_nl_cmd_policy,
.flags = GENL_ADMIN_PERM,
}, {
.cmd = MT753X_CMD_WRITE,
.doit = mt753x_nl_response,
// .policy = mt753x_nl_cmd_policy,
.flags = GENL_ADMIN_PERM,
},
};
static struct genl_family mt753x_nl_family = {
.name = MT753X_GENL_NAME,
.version = MT753X_GENL_VERSION,
.maxattr = MT753X_NR_ATTR_TYPE,
.ops = mt753x_nl_ops,
.n_ops = ARRAY_SIZE(mt753x_nl_ops),
};
static int mt753x_nl_list_devs(char *buff, int size)
{
struct gsw_mt753x *gsw;
int len, total = 0;
char buf[80];
memset(buff, 0, size);
mt753x_lock_gsw();
list_for_each_entry(gsw, &mt753x_devs, list) {
len = snprintf(buf, sizeof(buf),
"id: %d, model: %s, node: %s\n",
gsw->id, gsw->name, gsw->dev->of_node->name);
strncat(buff, buf, size - total);
total += len;
}
mt753x_put_gsw();
return total;
}
static int mt753x_nl_prepare_reply(struct genl_info *info, u8 cmd,
struct sk_buff **skbp)
{
struct sk_buff *msg;
void *reply;
if (!info)
return -EINVAL;
msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
if (!msg)
return -ENOMEM;
/* Construct send-back message header */
reply = genlmsg_put(msg, info->snd_portid, info->snd_seq,
&mt753x_nl_family, 0, cmd);
if (!reply) {
nlmsg_free(msg);
return -EINVAL;
}
*skbp = msg;
return 0;
}
static int mt753x_nl_send_reply(struct sk_buff *skb, struct genl_info *info)
{
struct genlmsghdr *genlhdr = nlmsg_data(nlmsg_hdr(skb));
void *reply = genlmsg_data(genlhdr);
/* Finalize a generic netlink message (update message header) */
genlmsg_end(skb, reply);
/* reply to a request */
return genlmsg_reply(skb, info);
}
static s32 mt753x_nl_get_s32(struct genl_info *info, enum mt753x_attr attr,
s32 defval)
{
struct nlattr *na;
na = info->attrs[attr];
if (na)
return nla_get_s32(na);
return defval;
}
static int mt753x_nl_get_u32(struct genl_info *info, enum mt753x_attr attr,
u32 *val)
{
struct nlattr *na;
na = info->attrs[attr];
if (na) {
*val = nla_get_u32(na);
return 0;
}
return -1;
}
static struct gsw_mt753x *mt753x_nl_parse_find_gsw(struct genl_info *info)
{
struct gsw_mt753x *gsw;
struct nlattr *na;
int gsw_id;
na = info->attrs[MT753X_ATTR_TYPE_DEV_ID];
if (na) {
gsw_id = nla_get_s32(na);
if (gsw_id >= 0)
gsw = mt753x_get_gsw(gsw_id);
else
gsw = mt753x_get_first_gsw();
} else {
gsw = mt753x_get_first_gsw();
}
return gsw;
}
static int mt753x_nl_get_swdevs(struct genl_info *info, struct gsw_mt753x *gsw)
{
struct sk_buff *rep_skb = NULL;
char dev_info[512];
int ret;
ret = mt753x_nl_list_devs(dev_info, sizeof(dev_info));
if (!ret) {
pr_info("No switch registered\n");
return -EINVAL;
}
ret = mt753x_nl_prepare_reply(info, MT753X_CMD_REPLY, &rep_skb);
if (ret < 0)
goto err;
ret = nla_put_string(rep_skb, MT753X_ATTR_TYPE_MESG, dev_info);
if (ret < 0)
goto err;
return mt753x_nl_send_reply(rep_skb, info);
err:
if (rep_skb)
nlmsg_free(rep_skb);
return ret;
}
static int mt753x_nl_reply_read(struct genl_info *info, struct gsw_mt753x *gsw)
{
struct sk_buff *rep_skb = NULL;
s32 phy, devad, reg;
int value;
int ret = 0;
phy = mt753x_nl_get_s32(info, MT753X_ATTR_TYPE_PHY, -1);
devad = mt753x_nl_get_s32(info, MT753X_ATTR_TYPE_DEVAD, -1);
reg = mt753x_nl_get_s32(info, MT753X_ATTR_TYPE_REG, -1);
if (reg < 0)
goto err;
ret = mt753x_nl_prepare_reply(info, MT753X_CMD_READ, &rep_skb);
if (ret < 0)
goto err;
if (phy >= 0) {
if (devad < 0)
value = gsw->mii_read(gsw, phy, reg);
else
value = gsw->mmd_read(gsw, phy, devad, reg);
} else {
value = mt753x_reg_read(gsw, reg);
}
ret = nla_put_s32(rep_skb, MT753X_ATTR_TYPE_REG, reg);
if (ret < 0)
goto err;
ret = nla_put_s32(rep_skb, MT753X_ATTR_TYPE_VAL, value);
if (ret < 0)
goto err;
return mt753x_nl_send_reply(rep_skb, info);
err:
if (rep_skb)
nlmsg_free(rep_skb);
return ret;
}
static int mt753x_nl_reply_write(struct genl_info *info, struct gsw_mt753x *gsw)
{
struct sk_buff *rep_skb = NULL;
s32 phy, devad, reg;
u32 value;
int ret = 0;
phy = mt753x_nl_get_s32(info, MT753X_ATTR_TYPE_PHY, -1);
devad = mt753x_nl_get_s32(info, MT753X_ATTR_TYPE_DEVAD, -1);
reg = mt753x_nl_get_s32(info, MT753X_ATTR_TYPE_REG, -1);
if (mt753x_nl_get_u32(info, MT753X_ATTR_TYPE_VAL, &value))
goto err;
if (reg < 0)
goto err;
ret = mt753x_nl_prepare_reply(info, MT753X_CMD_WRITE, &rep_skb);
if (ret < 0)
goto err;
if (phy >= 0) {
if (devad < 0)
gsw->mii_write(gsw, phy, reg, value);
else
gsw->mmd_write(gsw, phy, devad, reg, value);
} else {
mt753x_reg_write(gsw, reg, value);
}
ret = nla_put_s32(rep_skb, MT753X_ATTR_TYPE_REG, reg);
if (ret < 0)
goto err;
ret = nla_put_s32(rep_skb, MT753X_ATTR_TYPE_VAL, value);
if (ret < 0)
goto err;
return mt753x_nl_send_reply(rep_skb, info);
err:
if (rep_skb)
nlmsg_free(rep_skb);
return ret;
}
static const enum mt753x_attr mt753x_nl_cmd_read_attrs[] = {
MT753X_ATTR_TYPE_REG
};
static const enum mt753x_attr mt753x_nl_cmd_write_attrs[] = {
MT753X_ATTR_TYPE_REG,
MT753X_ATTR_TYPE_VAL
};
static const struct mt753x_nl_cmd_item mt753x_nl_cmds[] = {
{
.cmd = MT753X_CMD_REQUEST,
.require_dev = false,
.process = mt753x_nl_get_swdevs
}, {
.cmd = MT753X_CMD_READ,
.require_dev = true,
.process = mt753x_nl_reply_read,
.required_attrs = mt753x_nl_cmd_read_attrs,
.nr_required_attrs = ARRAY_SIZE(mt753x_nl_cmd_read_attrs),
}, {
.cmd = MT753X_CMD_WRITE,
.require_dev = true,
.process = mt753x_nl_reply_write,
.required_attrs = mt753x_nl_cmd_write_attrs,
.nr_required_attrs = ARRAY_SIZE(mt753x_nl_cmd_write_attrs),
}
};
static int mt753x_nl_response(struct sk_buff *skb, struct genl_info *info)
{
struct genlmsghdr *hdr = nlmsg_data(info->nlhdr);
const struct mt753x_nl_cmd_item *cmditem = NULL;
struct gsw_mt753x *gsw = NULL;
u32 sat_req_attrs = 0;
int i, ret;
for (i = 0; i < ARRAY_SIZE(mt753x_nl_cmds); i++) {
if (hdr->cmd == mt753x_nl_cmds[i].cmd) {
cmditem = &mt753x_nl_cmds[i];
break;
}
}
if (!cmditem) {
pr_info("mt753x-nl: unknown cmd %u\n", hdr->cmd);
return -EINVAL;
}
for (i = 0; i < cmditem->nr_required_attrs; i++) {
if (info->attrs[cmditem->required_attrs[i]])
sat_req_attrs++;
}
if (sat_req_attrs != cmditem->nr_required_attrs) {
pr_info("mt753x-nl: missing required attr(s) for cmd %u\n",
hdr->cmd);
return -EINVAL;
}
if (cmditem->require_dev) {
gsw = mt753x_nl_parse_find_gsw(info);
if (!gsw) {
pr_info("mt753x-nl: failed to find switch dev\n");
return -EINVAL;
}
}
ret = cmditem->process(info, gsw);
mt753x_put_gsw();
return ret;
}
int __init mt753x_nl_init(void)
{
int ret;
ret = genl_register_family(&mt753x_nl_family);
if (ret) {
pr_info("mt753x-nl: genl_register_family_with_ops failed\n");
return ret;
}
return 0;
}
void __exit mt753x_nl_exit(void)
{
genl_unregister_family(&mt753x_nl_family);
}

View file

@ -0,0 +1,43 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018 MediaTek Inc.
* Author: Sirui Zhao <Sirui.Zhao@mediatek.com>
*/
#ifndef _MT753X_NL_H_
#define _MT753X_NL_H_
#define MT753X_GENL_NAME "mt753x"
#define MT753X_GENL_VERSION 0x1
enum mt753x_cmd {
MT753X_CMD_UNSPEC = 0,
MT753X_CMD_REQUEST,
MT753X_CMD_REPLY,
MT753X_CMD_READ,
MT753X_CMD_WRITE,
__MT753X_CMD_MAX,
};
enum mt753x_attr {
MT753X_ATTR_TYPE_UNSPEC = 0,
MT753X_ATTR_TYPE_MESG,
MT753X_ATTR_TYPE_PHY,
MT753X_ATTR_TYPE_DEVAD,
MT753X_ATTR_TYPE_REG,
MT753X_ATTR_TYPE_VAL,
MT753X_ATTR_TYPE_DEV_NAME,
MT753X_ATTR_TYPE_DEV_ID,
__MT753X_ATTR_TYPE_MAX,
};
#define MT753X_NR_ATTR_TYPE (__MT753X_ATTR_TYPE_MAX - 1)
#ifdef __KERNEL__
int __init mt753x_nl_init(void);
void __exit mt753x_nl_exit(void);
#endif /* __KERNEL__ */
#endif /* _MT753X_NL_H_ */

View file

@ -0,0 +1,294 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018 MediaTek Inc.
* Author: Weijie Gao <weijie.gao@mediatek.com>
*/
#ifndef _MT753X_REGS_H_
#define _MT753X_REGS_H_
#include <linux/bitops.h>
/* Values of Egress TAG Control */
#define ETAG_CTRL_UNTAG 0
#define ETAG_CTRL_TAG 2
#define ETAG_CTRL_SWAP 1
#define ETAG_CTRL_STACK 3
#define VTCR 0x90
#define VAWD1 0x94
#define VAWD2 0x98
/* Fields of VTCR */
#define VTCR_BUSY BIT(31)
#define IDX_INVLD BIT(16)
#define VTCR_FUNC_S 12
#define VTCR_FUNC_M 0xf000
#define VTCR_VID_S 0
#define VTCR_VID_M 0xfff
/* Values of VTCR_FUNC */
#define VTCR_READ_VLAN_ENTRY 0
#define VTCR_WRITE_VLAN_ENTRY 1
#define VTCR_INVD_VLAN_ENTRY 2
#define VTCR_ENABLE_VLAN_ENTRY 3
#define VTCR_READ_ACL_ENTRY 4
#define VTCR_WRITE_ACL_ENTRY 5
#define VTCR_READ_TRTCM_TABLE 6
#define VTCR_WRITE_TRTCM_TABLE 7
#define VTCR_READ_ACL_MASK_ENTRY 8
#define VTCR_WRITE_ACL_MASK_ENTRY 9
#define VTCR_READ_ACL_RULE_ENTRY 10
#define VTCR_WRITE_ACL_RULE_ENTRY 11
#define VTCR_READ_ACL_RATE_ENTRY 12
#define VTCR_WRITE_ACL_RATE_ENTRY 13
/* VLAN entry fields */
/* VAWD1 */
#define PORT_STAG BIT(31)
#define IVL_MAC BIT(30)
#define EG_CON BIT(29)
#define VTAG_EN BIT(28)
#define COPY_PRI BIT(27)
#define USER_PRI_S 24
#define USER_PRI_M 0x7000000
#define PORT_MEM_S 16
#define PORT_MEM_M 0xff0000
#define S_TAG1_S 4
#define S_TAG1_M 0xfff0
#define FID_S 1
#define FID_M 0x0e
#define VENTRY_VALID BIT(0)
/* VAWD2 */
#define S_TAG2_S 16
#define S_TAG2_M 0xffff0000
#define PORT_ETAG_S(p) ((p) * 2)
#define PORT_ETAG_M 0x03
#define PORT_CTRL_BASE 0x2000
#define PORT_CTRL_PORT_OFFSET 0x100
#define PORT_CTRL_REG(p, r) (PORT_CTRL_BASE + \
(p) * PORT_CTRL_PORT_OFFSET + (r))
#define CKGCR(p) PORT_CTRL_REG(p, 0x00)
#define PCR(p) PORT_CTRL_REG(p, 0x04)
#define PIC(p) PORT_CTRL_REG(p, 0x08)
#define PSC(p) PORT_CTRL_REG(p, 0x0c)
#define PVC(p) PORT_CTRL_REG(p, 0x10)
#define PPBV1(p) PORT_CTRL_REG(p, 0x14)
#define PPBV2(p) PORT_CTRL_REG(p, 0x18)
#define BSR(p) PORT_CTRL_REG(p, 0x1c)
#define STAG01 PORT_CTRL_REG(p, 0x20)
#define STAG23 PORT_CTRL_REG(p, 0x24)
#define STAG45 PORT_CTRL_REG(p, 0x28)
#define STAG67 PORT_CTRL_REG(p, 0x2c)
#define PPBV(p, g) (PPBV1(p) + ((g) / 2) * 4)
/* Fields of PCR */
#define MLDV2_EN BIT(30)
#define EG_TAG_S 28
#define EG_TAG_M 0x30000000
#define PORT_PRI_S 24
#define PORT_PRI_M 0x7000000
#define PORT_MATRIX_S 16
#define PORT_MATRIX_M 0xff0000
#define UP2DSCP_EN BIT(12)
#define UP2TAG_EN BIT(11)
#define ACL_EN BIT(10)
#define PORT_TX_MIR BIT(9)
#define PORT_RX_MIR BIT(8)
#define ACL_MIR BIT(7)
#define MIS_PORT_FW_S 4
#define MIS_PORT_FW_M 0x70
#define VLAN_MIS BIT(2)
#define PORT_VLAN_S 0
#define PORT_VLAN_M 0x03
/* Values of PORT_VLAN */
#define PORT_MATRIX_MODE 0
#define FALLBACK_MODE 1
#define CHECK_MODE 2
#define SECURITY_MODE 3
/* Fields of PVC */
#define STAG_VPID_S 16
#define STAG_VPID_M 0xffff0000
#define DIS_PVID BIT(15)
#define FORCE_PVID BIT(14)
#define PT_VPM BIT(12)
#define PT_OPTION BIT(11)
#define PVC_EG_TAG_S 8
#define PVC_EG_TAG_M 0x700
#define VLAN_ATTR_S 6
#define VLAN_ATTR_M 0xc0
#define PVC_PORT_STAG BIT(5)
#define BC_LKYV_EN BIT(4)
#define MC_LKYV_EN BIT(3)
#define UC_LKYV_EN BIT(2)
#define ACC_FRM_S 0
#define ACC_FRM_M 0x03
/* Values of VLAN_ATTR */
#define VA_USER_PORT 0
#define VA_STACK_PORT 1
#define VA_TRANSLATION_PORT 2
#define VA_TRANSPARENT_PORT 3
/* Fields of PPBV */
#define GRP_PORT_PRI_S(g) (((g) % 2) * 16 + 13)
#define GRP_PORT_PRI_M 0x07
#define GRP_PORT_VID_S(g) (((g) % 2) * 16)
#define GRP_PORT_VID_M 0xfff
#define PORT_MAC_CTRL_BASE 0x3000
#define PORT_MAC_CTRL_PORT_OFFSET 0x100
#define PORT_MAC_CTRL_REG(p, r) (PORT_MAC_CTRL_BASE + \
(p) * PORT_MAC_CTRL_PORT_OFFSET + (r))
#define PMCR(p) PORT_MAC_CTRL_REG(p, 0x00)
#define PMEEECR(p) PORT_MAC_CTRL_REG(p, 0x04)
#define PMSR(p) PORT_MAC_CTRL_REG(p, 0x08)
#define PINT_EN(p) PORT_MAC_CTRL_REG(p, 0x10)
#define PINT_STS(p) PORT_MAC_CTRL_REG(p, 0x14)
#define GMACCR (PORT_MAC_CTRL_BASE + 0xe0)
#define TXCRC_EN BIT(19)
#define RXCRC_EN BIT(18)
#define PRMBL_LMT_EN BIT(17)
#define MTCC_LMT_S 9
#define MTCC_LMT_M 0x1e00
#define MAX_RX_JUMBO_S 2
#define MAX_RX_JUMBO_M 0x3c
#define MAX_RX_PKT_LEN_S 0
#define MAX_RX_PKT_LEN_M 0x3
/* Values of MAX_RX_PKT_LEN */
#define RX_PKT_LEN_1518 0
#define RX_PKT_LEN_1536 1
#define RX_PKT_LEN_1522 2
#define RX_PKT_LEN_MAX_JUMBO 3
/* Fields of PMCR */
#define IPG_CFG_S 18
#define IPG_CFG_M 0xc0000
#define EXT_PHY BIT(17)
#define MAC_MODE BIT(16)
#define MAC_TX_EN BIT(14)
#define MAC_RX_EN BIT(13)
#define MAC_PRE BIT(11)
#define BKOFF_EN BIT(9)
#define BACKPR_EN BIT(8)
#define FORCE_EEE1G BIT(7)
#define FORCE_EEE1000 BIT(6)
#define FORCE_RX_FC BIT(5)
#define FORCE_TX_FC BIT(4)
#define FORCE_SPD_S 2
#define FORCE_SPD_M 0x0c
#define FORCE_DPX BIT(1)
#define FORCE_LINK BIT(0)
/* Fields of PMSR */
#define EEE1G_STS BIT(7)
#define EEE100_STS BIT(6)
#define RX_FC_STS BIT(5)
#define TX_FC_STS BIT(4)
#define MAC_SPD_STS_S 2
#define MAC_SPD_STS_M 0x0c
#define MAC_DPX_STS BIT(1)
#define MAC_LNK_STS BIT(0)
/* Values of MAC_SPD_STS */
#define MAC_SPD_10 0
#define MAC_SPD_100 1
#define MAC_SPD_1000 2
#define MAC_SPD_2500 3
/* Values of IPG_CFG */
#define IPG_96BIT 0
#define IPG_96BIT_WITH_SHORT_IPG 1
#define IPG_64BIT 2
#define MIB_COUNTER_BASE 0x4000
#define MIB_COUNTER_PORT_OFFSET 0x100
#define MIB_COUNTER_REG(p, r) (MIB_COUNTER_BASE + \
(p) * MIB_COUNTER_PORT_OFFSET + (r))
#define STATS_TDPC 0x00
#define STATS_TCRC 0x04
#define STATS_TUPC 0x08
#define STATS_TMPC 0x0C
#define STATS_TBPC 0x10
#define STATS_TCEC 0x14
#define STATS_TSCEC 0x18
#define STATS_TMCEC 0x1C
#define STATS_TDEC 0x20
#define STATS_TLCEC 0x24
#define STATS_TXCEC 0x28
#define STATS_TPPC 0x2C
#define STATS_TL64PC 0x30
#define STATS_TL65PC 0x34
#define STATS_TL128PC 0x38
#define STATS_TL256PC 0x3C
#define STATS_TL512PC 0x40
#define STATS_TL1024PC 0x44
#define STATS_TOC 0x48
#define STATS_RDPC 0x60
#define STATS_RFPC 0x64
#define STATS_RUPC 0x68
#define STATS_RMPC 0x6C
#define STATS_RBPC 0x70
#define STATS_RAEPC 0x74
#define STATS_RCEPC 0x78
#define STATS_RUSPC 0x7C
#define STATS_RFEPC 0x80
#define STATS_ROSPC 0x84
#define STATS_RJEPC 0x88
#define STATS_RPPC 0x8C
#define STATS_RL64PC 0x90
#define STATS_RL65PC 0x94
#define STATS_RL128PC 0x98
#define STATS_RL256PC 0x9C
#define STATS_RL512PC 0xA0
#define STATS_RL1024PC 0xA4
#define STATS_ROC 0xA8
#define STATS_RDPC_CTRL 0xB0
#define STATS_RDPC_ING 0xB4
#define STATS_RDPC_ARL 0xB8
#define SYS_CTRL 0x7000
#define SW_PHY_RST BIT(2)
#define SW_SYS_RST BIT(1)
#define SW_REG_RST BIT(0)
#define SYS_INT_EN 0x7008
#define SYS_INT_STS 0x700c
#define MAC_PC_INT BIT(16)
#define PHY_INT(p) BIT((p) + 8)
#define PHY_LC_INT(p) BIT(p)
#define PHY_IAC 0x701c
#define PHY_ACS_ST BIT(31)
#define MDIO_REG_ADDR_S 25
#define MDIO_REG_ADDR_M 0x3e000000
#define MDIO_PHY_ADDR_S 20
#define MDIO_PHY_ADDR_M 0x1f00000
#define MDIO_CMD_S 18
#define MDIO_CMD_M 0xc0000
#define MDIO_ST_S 16
#define MDIO_ST_M 0x30000
#define MDIO_RW_DATA_S 0
#define MDIO_RW_DATA_M 0xffff
/* MDIO_CMD: MDIO commands */
#define MDIO_CMD_ADDR 0
#define MDIO_CMD_WRITE 1
#define MDIO_CMD_READ 2
#define MDIO_CMD_READ_C45 3
/* MDIO_ST: MDIO start field */
#define MDIO_ST_C45 0
#define MDIO_ST_C22 1
#define HWSTRAP 0x7800
#define MHWSTRAP 0x7804
#endif /* _MT753X_REGS_H_ */

View file

@ -0,0 +1,510 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018 MediaTek Inc.
* Author: Weijie Gao <weijie.gao@mediatek.com>
*/
#include <linux/if.h>
#include <linux/list.h>
#include <linux/if_ether.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/netlink.h>
#include <linux/bitops.h>
#include <net/genetlink.h>
#include <linux/delay.h>
#include <linux/phy.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/lockdep.h>
#include <linux/workqueue.h>
#include <linux/of_device.h>
#include "mt753x.h"
#include "mt753x_swconfig.h"
#include "mt753x_regs.h"
#define MT753X_PORT_MIB_TXB_ID 18 /* TxByte */
#define MT753X_PORT_MIB_RXB_ID 37 /* RxByte */
#define MIB_DESC(_s, _o, _n) \
{ \
.size = (_s), \
.offset = (_o), \
.name = (_n), \
}
struct mt753x_mib_desc {
unsigned int size;
unsigned int offset;
const char *name;
};
static const struct mt753x_mib_desc mt753x_mibs[] = {
MIB_DESC(1, STATS_TDPC, "TxDrop"),
MIB_DESC(1, STATS_TCRC, "TxCRC"),
MIB_DESC(1, STATS_TUPC, "TxUni"),
MIB_DESC(1, STATS_TMPC, "TxMulti"),
MIB_DESC(1, STATS_TBPC, "TxBroad"),
MIB_DESC(1, STATS_TCEC, "TxCollision"),
MIB_DESC(1, STATS_TSCEC, "TxSingleCol"),
MIB_DESC(1, STATS_TMCEC, "TxMultiCol"),
MIB_DESC(1, STATS_TDEC, "TxDefer"),
MIB_DESC(1, STATS_TLCEC, "TxLateCol"),
MIB_DESC(1, STATS_TXCEC, "TxExcCol"),
MIB_DESC(1, STATS_TPPC, "TxPause"),
MIB_DESC(1, STATS_TL64PC, "Tx64Byte"),
MIB_DESC(1, STATS_TL65PC, "Tx65Byte"),
MIB_DESC(1, STATS_TL128PC, "Tx128Byte"),
MIB_DESC(1, STATS_TL256PC, "Tx256Byte"),
MIB_DESC(1, STATS_TL512PC, "Tx512Byte"),
MIB_DESC(1, STATS_TL1024PC, "Tx1024Byte"),
MIB_DESC(2, STATS_TOC, "TxByte"),
MIB_DESC(1, STATS_RDPC, "RxDrop"),
MIB_DESC(1, STATS_RFPC, "RxFiltered"),
MIB_DESC(1, STATS_RUPC, "RxUni"),
MIB_DESC(1, STATS_RMPC, "RxMulti"),
MIB_DESC(1, STATS_RBPC, "RxBroad"),
MIB_DESC(1, STATS_RAEPC, "RxAlignErr"),
MIB_DESC(1, STATS_RCEPC, "RxCRC"),
MIB_DESC(1, STATS_RUSPC, "RxUnderSize"),
MIB_DESC(1, STATS_RFEPC, "RxFragment"),
MIB_DESC(1, STATS_ROSPC, "RxOverSize"),
MIB_DESC(1, STATS_RJEPC, "RxJabber"),
MIB_DESC(1, STATS_RPPC, "RxPause"),
MIB_DESC(1, STATS_RL64PC, "Rx64Byte"),
MIB_DESC(1, STATS_RL65PC, "Rx65Byte"),
MIB_DESC(1, STATS_RL128PC, "Rx128Byte"),
MIB_DESC(1, STATS_RL256PC, "Rx256Byte"),
MIB_DESC(1, STATS_RL512PC, "Rx512Byte"),
MIB_DESC(1, STATS_RL1024PC, "Rx1024Byte"),
MIB_DESC(2, STATS_ROC, "RxByte"),
MIB_DESC(1, STATS_RDPC_CTRL, "RxCtrlDrop"),
MIB_DESC(1, STATS_RDPC_ING, "RxIngDrop"),
MIB_DESC(1, STATS_RDPC_ARL, "RxARLDrop")
};
enum {
/* Global attributes. */
MT753X_ATTR_ENABLE_VLAN,
};
static int mt753x_get_vlan_enable(struct switch_dev *dev,
const struct switch_attr *attr,
struct switch_val *val)
{
struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
val->value.i = gsw->global_vlan_enable;
return 0;
}
static int mt753x_set_vlan_enable(struct switch_dev *dev,
const struct switch_attr *attr,
struct switch_val *val)
{
struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
gsw->global_vlan_enable = val->value.i != 0;
return 0;
}
static int mt753x_get_port_pvid(struct switch_dev *dev, int port, int *val)
{
struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
if (port >= MT753X_NUM_PORTS)
return -EINVAL;
*val = mt753x_reg_read(gsw, PPBV1(port));
*val &= GRP_PORT_VID_M;
return 0;
}
static int mt753x_set_port_pvid(struct switch_dev *dev, int port, int pvid)
{
struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
if (port >= MT753X_NUM_PORTS)
return -EINVAL;
if (pvid < MT753X_MIN_VID || pvid > MT753X_MAX_VID)
return -EINVAL;
gsw->port_entries[port].pvid = pvid;
return 0;
}
static int mt753x_get_vlan_ports(struct switch_dev *dev, struct switch_val *val)
{
struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
u32 member;
u32 etags;
int i;
val->len = 0;
if (val->port_vlan < 0 || val->port_vlan >= MT753X_NUM_VLANS)
return -EINVAL;
mt753x_vlan_ctrl(gsw, VTCR_READ_VLAN_ENTRY, val->port_vlan);
member = mt753x_reg_read(gsw, VAWD1);
member &= PORT_MEM_M;
member >>= PORT_MEM_S;
etags = mt753x_reg_read(gsw, VAWD2);
for (i = 0; i < MT753X_NUM_PORTS; i++) {
struct switch_port *p;
int etag;
if (!(member & BIT(i)))
continue;
p = &val->value.ports[val->len++];
p->id = i;
etag = (etags >> PORT_ETAG_S(i)) & PORT_ETAG_M;
if (etag == ETAG_CTRL_TAG)
p->flags |= BIT(SWITCH_PORT_FLAG_TAGGED);
else if (etag != ETAG_CTRL_UNTAG)
dev_info(gsw->dev,
"vlan egress tag control neither untag nor tag.\n");
}
return 0;
}
static int mt753x_set_vlan_ports(struct switch_dev *dev, struct switch_val *val)
{
struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
u8 member = 0;
u8 etags = 0;
int i;
if (val->port_vlan < 0 || val->port_vlan >= MT753X_NUM_VLANS ||
val->len > MT753X_NUM_PORTS)
return -EINVAL;
for (i = 0; i < val->len; i++) {
struct switch_port *p = &val->value.ports[i];
if (p->id >= MT753X_NUM_PORTS)
return -EINVAL;
member |= BIT(p->id);
if (p->flags & BIT(SWITCH_PORT_FLAG_TAGGED))
etags |= BIT(p->id);
}
gsw->vlan_entries[val->port_vlan].member = member;
gsw->vlan_entries[val->port_vlan].etags = etags;
return 0;
}
static int mt753x_set_vid(struct switch_dev *dev,
const struct switch_attr *attr,
struct switch_val *val)
{
struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
int vlan;
u16 vid;
vlan = val->port_vlan;
vid = (u16)val->value.i;
if (vlan < 0 || vlan >= MT753X_NUM_VLANS)
return -EINVAL;
if (vid < MT753X_MIN_VID || vid > MT753X_MAX_VID)
return -EINVAL;
gsw->vlan_entries[vlan].vid = vid;
return 0;
}
static int mt753x_get_vid(struct switch_dev *dev,
const struct switch_attr *attr,
struct switch_val *val)
{
val->value.i = val->port_vlan;
return 0;
}
static int mt753x_get_port_link(struct switch_dev *dev, int port,
struct switch_port_link *link)
{
struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
u32 speed, pmsr;
if (port < 0 || port >= MT753X_NUM_PORTS)
return -EINVAL;
pmsr = mt753x_reg_read(gsw, PMSR(port));
link->link = pmsr & MAC_LNK_STS;
link->duplex = pmsr & MAC_DPX_STS;
speed = (pmsr & MAC_SPD_STS_M) >> MAC_SPD_STS_S;
switch (speed) {
case MAC_SPD_10:
link->speed = SWITCH_PORT_SPEED_10;
break;
case MAC_SPD_100:
link->speed = SWITCH_PORT_SPEED_100;
break;
case MAC_SPD_1000:
link->speed = SWITCH_PORT_SPEED_1000;
break;
case MAC_SPD_2500:
/* TODO: swconfig has no support for 2500 now */
link->speed = SWITCH_PORT_SPEED_UNKNOWN;
break;
}
return 0;
}
static int mt753x_set_port_link(struct switch_dev *dev, int port,
struct switch_port_link *link)
{
#ifndef MODULE
if (port >= MT753X_NUM_PHYS)
return -EINVAL;
return switch_generic_set_link(dev, port, link);
#else
return -ENOTSUPP;
#endif
}
static u64 get_mib_counter(struct gsw_mt753x *gsw, int i, int port)
{
unsigned int offset;
u64 lo, hi, hi2;
offset = mt753x_mibs[i].offset;
if (mt753x_mibs[i].size == 1)
return mt753x_reg_read(gsw, MIB_COUNTER_REG(port, offset));
do {
hi = mt753x_reg_read(gsw, MIB_COUNTER_REG(port, offset + 4));
lo = mt753x_reg_read(gsw, MIB_COUNTER_REG(port, offset));
hi2 = mt753x_reg_read(gsw, MIB_COUNTER_REG(port, offset + 4));
} while (hi2 != hi);
return (hi << 32) | lo;
}
static int mt753x_get_port_mib(struct switch_dev *dev,
const struct switch_attr *attr,
struct switch_val *val)
{
static char buf[4096];
struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
int i, len = 0;
if (val->port_vlan >= MT753X_NUM_PORTS)
return -EINVAL;
len += snprintf(buf + len, sizeof(buf) - len,
"Port %d MIB counters\n", val->port_vlan);
for (i = 0; i < ARRAY_SIZE(mt753x_mibs); ++i) {
u64 counter;
len += snprintf(buf + len, sizeof(buf) - len,
"%-11s: ", mt753x_mibs[i].name);
counter = get_mib_counter(gsw, i, val->port_vlan);
len += snprintf(buf + len, sizeof(buf) - len, "%llu\n",
counter);
}
val->value.s = buf;
val->len = len;
return 0;
}
static int mt753x_get_port_stats(struct switch_dev *dev, int port,
struct switch_port_stats *stats)
{
struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
if (port < 0 || port >= MT753X_NUM_PORTS)
return -EINVAL;
stats->tx_bytes = get_mib_counter(gsw, MT753X_PORT_MIB_TXB_ID, port);
stats->rx_bytes = get_mib_counter(gsw, MT753X_PORT_MIB_RXB_ID, port);
return 0;
}
static void mt753x_port_isolation(struct gsw_mt753x *gsw)
{
int i;
for (i = 0; i < MT753X_NUM_PORTS; i++)
mt753x_reg_write(gsw, PCR(i),
BIT(gsw->cpu_port) << PORT_MATRIX_S);
mt753x_reg_write(gsw, PCR(gsw->cpu_port), PORT_MATRIX_M);
for (i = 0; i < MT753X_NUM_PORTS; i++)
mt753x_reg_write(gsw, PVC(i),
(0x8100 << STAG_VPID_S) |
(VA_TRANSPARENT_PORT << VLAN_ATTR_S));
}
static int mt753x_apply_config(struct switch_dev *dev)
{
struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
if (!gsw->global_vlan_enable) {
mt753x_port_isolation(gsw);
return 0;
}
mt753x_apply_vlan_config(gsw);
return 0;
}
static int mt753x_reset_switch(struct switch_dev *dev)
{
struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
int i;
memset(gsw->port_entries, 0, sizeof(gsw->port_entries));
memset(gsw->vlan_entries, 0, sizeof(gsw->vlan_entries));
/* set default vid of each vlan to the same number of vlan, so the vid
* won't need be set explicitly.
*/
for (i = 0; i < MT753X_NUM_VLANS; i++)
gsw->vlan_entries[i].vid = i;
return 0;
}
static int mt753x_phy_read16(struct switch_dev *dev, int addr, u8 reg,
u16 *value)
{
struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
*value = gsw->mii_read(gsw, addr, reg);
return 0;
}
static int mt753x_phy_write16(struct switch_dev *dev, int addr, u8 reg,
u16 value)
{
struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
gsw->mii_write(gsw, addr, reg, value);
return 0;
}
static const struct switch_attr mt753x_global[] = {
{
.type = SWITCH_TYPE_INT,
.name = "enable_vlan",
.description = "VLAN mode (1:enabled)",
.max = 1,
.id = MT753X_ATTR_ENABLE_VLAN,
.get = mt753x_get_vlan_enable,
.set = mt753x_set_vlan_enable,
}
};
static const struct switch_attr mt753x_port[] = {
{
.type = SWITCH_TYPE_STRING,
.name = "mib",
.description = "Get MIB counters for port",
.get = mt753x_get_port_mib,
.set = NULL,
},
};
static const struct switch_attr mt753x_vlan[] = {
{
.type = SWITCH_TYPE_INT,
.name = "vid",
.description = "VLAN ID (0-4094)",
.set = mt753x_set_vid,
.get = mt753x_get_vid,
.max = 4094,
},
};
static const struct switch_dev_ops mt753x_swdev_ops = {
.attr_global = {
.attr = mt753x_global,
.n_attr = ARRAY_SIZE(mt753x_global),
},
.attr_port = {
.attr = mt753x_port,
.n_attr = ARRAY_SIZE(mt753x_port),
},
.attr_vlan = {
.attr = mt753x_vlan,
.n_attr = ARRAY_SIZE(mt753x_vlan),
},
.get_vlan_ports = mt753x_get_vlan_ports,
.set_vlan_ports = mt753x_set_vlan_ports,
.get_port_pvid = mt753x_get_port_pvid,
.set_port_pvid = mt753x_set_port_pvid,
.get_port_link = mt753x_get_port_link,
.set_port_link = mt753x_set_port_link,
.get_port_stats = mt753x_get_port_stats,
.apply_config = mt753x_apply_config,
.reset_switch = mt753x_reset_switch,
.phy_read16 = mt753x_phy_read16,
.phy_write16 = mt753x_phy_write16,
};
int mt753x_swconfig_init(struct gsw_mt753x *gsw)
{
struct device_node *np = gsw->dev->of_node;
struct switch_dev *swdev;
int ret;
if (of_property_read_u32(np, "mediatek,cpuport", &gsw->cpu_port))
gsw->cpu_port = MT753X_DFL_CPU_PORT;
swdev = &gsw->swdev;
swdev->name = gsw->name;
swdev->alias = gsw->name;
swdev->cpu_port = gsw->cpu_port;
swdev->ports = MT753X_NUM_PORTS;
swdev->vlans = MT753X_NUM_VLANS;
swdev->ops = &mt753x_swdev_ops;
ret = register_switch(swdev, NULL);
if (ret) {
dev_notice(gsw->dev, "Failed to register switch %s\n",
swdev->name);
return ret;
}
mt753x_apply_config(swdev);
return 0;
}
void mt753x_swconfig_destroy(struct gsw_mt753x *gsw)
{
unregister_switch(&gsw->swdev);
}

View file

@ -0,0 +1,29 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018 MediaTek Inc.
* Author: Weijie Gao <weijie.gao@mediatek.com>
*/
#ifndef _MT753X_SWCONFIG_H_
#define _MT753X_SWCONFIG_H_
#ifdef CONFIG_SWCONFIG
#include <linux/switch.h>
#include "mt753x.h"
int mt753x_swconfig_init(struct gsw_mt753x *gsw);
void mt753x_swconfig_destroy(struct gsw_mt753x *gsw);
#else
static inline int mt753x_swconfig_init(struct gsw_mt753x *gsw)
{
mt753x_apply_vlan_config(gsw);
return 0;
}
static inline void mt753x_swconfig_destroy(struct gsw_mt753x *gsw)
{
}
#endif
#endif /* _MT753X_SWCONFIG_H_ */

View file

@ -0,0 +1,183 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018 MediaTek Inc.
*/
#include "mt753x.h"
#include "mt753x_regs.h"
struct mt753x_mapping mt753x_def_mapping[] = {
{
.name = "llllw",
.pvids = { 1, 1, 1, 1, 2, 2, 1 },
.members = { 0, 0x4f, 0x30 },
.etags = { 0, 0, 0 },
.vids = { 0, 1, 2 },
}, {
.name = "wllll",
.pvids = { 2, 1, 1, 1, 1, 2, 1 },
.members = { 0, 0x5e, 0x21 },
.etags = { 0, 0, 0 },
.vids = { 0, 1, 2 },
}, {
.name = "lwlll",
.pvids = { 1, 2, 1, 1, 1, 2, 1 },
.members = { 0, 0x5d, 0x22 },
.etags = { 0, 0, 0 },
.vids = { 0, 1, 2 },
},
};
void mt753x_vlan_ctrl(struct gsw_mt753x *gsw, u32 cmd, u32 val)
{
int i;
mt753x_reg_write(gsw, VTCR,
VTCR_BUSY | ((cmd << VTCR_FUNC_S) & VTCR_FUNC_M) |
(val & VTCR_VID_M));
for (i = 0; i < 300; i++) {
u32 val = mt753x_reg_read(gsw, VTCR);
if ((val & VTCR_BUSY) == 0)
break;
usleep_range(1000, 1100);
}
if (i == 300)
dev_info(gsw->dev, "vtcr timeout\n");
}
static void mt753x_write_vlan_entry(struct gsw_mt753x *gsw, int vlan, u16 vid,
u8 ports, u8 etags)
{
int port;
u32 val;
/* vlan port membership */
if (ports)
mt753x_reg_write(gsw, VAWD1,
IVL_MAC | VTAG_EN | VENTRY_VALID |
((ports << PORT_MEM_S) & PORT_MEM_M));
else
mt753x_reg_write(gsw, VAWD1, 0);
/* egress mode */
val = 0;
for (port = 0; port < MT753X_NUM_PORTS; port++) {
if (etags & BIT(port))
val |= ETAG_CTRL_TAG << PORT_ETAG_S(port);
else
val |= ETAG_CTRL_UNTAG << PORT_ETAG_S(port);
}
mt753x_reg_write(gsw, VAWD2, val);
/* write to vlan table */
mt753x_vlan_ctrl(gsw, VTCR_WRITE_VLAN_ENTRY, vid);
}
void mt753x_apply_vlan_config(struct gsw_mt753x *gsw)
{
int i, j;
u8 tag_ports;
u8 untag_ports;
/* set all ports as security mode */
for (i = 0; i < MT753X_NUM_PORTS; i++)
mt753x_reg_write(gsw, PCR(i),
PORT_MATRIX_M | SECURITY_MODE);
/* check if a port is used in tag/untag vlan egress mode */
tag_ports = 0;
untag_ports = 0;
for (i = 0; i < MT753X_NUM_VLANS; i++) {
u8 member = gsw->vlan_entries[i].member;
u8 etags = gsw->vlan_entries[i].etags;
if (!member)
continue;
for (j = 0; j < MT753X_NUM_PORTS; j++) {
if (!(member & BIT(j)))
continue;
if (etags & BIT(j))
tag_ports |= 1u << j;
else
untag_ports |= 1u << j;
}
}
/* set all untag-only ports as transparent and the rest as user port */
for (i = 0; i < MT753X_NUM_PORTS; i++) {
u32 pvc_mode = 0x8100 << STAG_VPID_S;
if (untag_ports & BIT(i) && !(tag_ports & BIT(i)))
pvc_mode = (0x8100 << STAG_VPID_S) |
(VA_TRANSPARENT_PORT << VLAN_ATTR_S);
mt753x_reg_write(gsw, PVC(i), pvc_mode);
}
/* first clear the switch vlan table */
for (i = 0; i < MT753X_NUM_VLANS; i++)
mt753x_write_vlan_entry(gsw, i, i, 0, 0);
/* now program only vlans with members to avoid
* clobbering remapped entries in later iterations
*/
for (i = 0; i < MT753X_NUM_VLANS; i++) {
u16 vid = gsw->vlan_entries[i].vid;
u8 member = gsw->vlan_entries[i].member;
u8 etags = gsw->vlan_entries[i].etags;
if (member)
mt753x_write_vlan_entry(gsw, i, vid, member, etags);
}
/* Port Default PVID */
for (i = 0; i < MT753X_NUM_PORTS; i++) {
int vlan = gsw->port_entries[i].pvid;
u16 pvid = 0;
u32 val;
if (vlan < MT753X_NUM_VLANS && gsw->vlan_entries[vlan].member)
pvid = gsw->vlan_entries[vlan].vid;
val = mt753x_reg_read(gsw, PPBV1(i));
val &= ~GRP_PORT_VID_M;
val |= pvid;
mt753x_reg_write(gsw, PPBV1(i), val);
}
}
struct mt753x_mapping *mt753x_find_mapping(struct device_node *np)
{
const char *map;
int i;
if (of_property_read_string(np, "mediatek,portmap", &map))
return NULL;
for (i = 0; i < ARRAY_SIZE(mt753x_def_mapping); i++)
if (!strcmp(map, mt753x_def_mapping[i].name))
return &mt753x_def_mapping[i];
return NULL;
}
void mt753x_apply_mapping(struct gsw_mt753x *gsw, struct mt753x_mapping *map)
{
int i = 0;
for (i = 0; i < MT753X_NUM_PORTS; i++)
gsw->port_entries[i].pvid = map->pvids[i];
for (i = 0; i < MT753X_NUM_VLANS; i++) {
gsw->vlan_entries[i].member = map->members[i];
gsw->vlan_entries[i].etags = map->etags[i];
gsw->vlan_entries[i].vid = map->vids[i];
}
}

View file

@ -0,0 +1,40 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018 MediaTek Inc.
*/
#ifndef _MT753X_VLAN_H_
#define _MT753X_VLAN_H_
#define MT753X_NUM_PORTS 7
#define MT753X_NUM_VLANS 4095
#define MT753X_MAX_VID 4095
#define MT753X_MIN_VID 0
struct gsw_mt753x;
struct mt753x_port_entry {
u16 pvid;
};
struct mt753x_vlan_entry {
u16 vid;
u8 member;
u8 etags;
};
struct mt753x_mapping {
char *name;
u16 pvids[MT753X_NUM_PORTS];
u8 members[MT753X_NUM_VLANS];
u8 etags[MT753X_NUM_VLANS];
u16 vids[MT753X_NUM_VLANS];
};
extern struct mt753x_mapping mt753x_defaults[];
void mt753x_vlan_ctrl(struct gsw_mt753x *gsw, u32 cmd, u32 val);
void mt753x_apply_vlan_config(struct gsw_mt753x *gsw);
struct mt753x_mapping *mt753x_find_mapping(struct device_node *np);
void mt753x_apply_mapping(struct gsw_mt753x *gsw, struct mt753x_mapping *map);
#endif /* _MT753X_VLAN_H_ */

View file

@ -0,0 +1,66 @@
obj-$(CONFIG_RTL8367S_GSW) += rtl8367s_gsw.o
rtl8367s_gsw-objs := rtl8367s_mdio.o rtl8367s_dbg.o
ifeq ($(CONFIG_SWCONFIG),y)
rtl8367s_gsw-objs += rtl8367s.o
endif
rtl8367s_gsw-objs += rtl8367c/acl.o
rtl8367s_gsw-objs += rtl8367c/cpu.o
rtl8367s_gsw-objs += rtl8367c/dot1x.o
rtl8367s_gsw-objs += rtl8367c/eee.o
rtl8367s_gsw-objs += rtl8367c/igmp.o
rtl8367s_gsw-objs += rtl8367c/interrupt.o
rtl8367s_gsw-objs += rtl8367c/l2.o
rtl8367s_gsw-objs += rtl8367c/leaky.o
rtl8367s_gsw-objs += rtl8367c/led.o
rtl8367s_gsw-objs += rtl8367c/mirror.o
rtl8367s_gsw-objs += rtl8367c/oam.o
rtl8367s_gsw-objs += rtl8367c/port.o
rtl8367s_gsw-objs += rtl8367c/ptp.o
rtl8367s_gsw-objs += rtl8367c/qos.o
rtl8367s_gsw-objs += rtl8367c/rate.o
rtl8367s_gsw-objs += rtl8367c/rldp.o
rtl8367s_gsw-objs += rtl8367c/rtk_switch.o
rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_acl.o
rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv.o
rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_cputag.o
rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_dot1x.o
rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_eav.o
rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_eee.o
rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_fc.o
rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_green.o
rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_hsb.o
rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_igmp.o
rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_inbwctrl.o
rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_interrupt.o
rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_led.o
rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_lut.o
rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_meter.o
rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_mib.o
rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_mirror.o
rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_misc.o
rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_oam.o
rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_phy.o
rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_port.o
rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_portIsolation.o
rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_qos.o
rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_rldp.o
rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_rma.o
rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_scheduling.o
rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_storm.o
rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_svlan.o
rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_trunking.o
rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_unknownMulticast.o
rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_vlan.o
rtl8367s_gsw-objs += rtl8367c/smi.o
rtl8367s_gsw-objs += rtl8367c/stat.o
rtl8367s_gsw-objs += rtl8367c/storm.o
rtl8367s_gsw-objs += rtl8367c/svlan.o
rtl8367s_gsw-objs += rtl8367c/trap.o
rtl8367s_gsw-objs += rtl8367c/trunk.o
rtl8367s_gsw-objs += rtl8367c/vlan.o
ccflags-y += -Werror -D_LITTLE_ENDIAN -DMDC_MDIO_OPERATION
ccflags-y += -Idrivers/net/phy/rtk/rtl8367c/include
ccflags-y += -Iinclude/linux/

View file

@ -0,0 +1 @@
kernel/drivers/net/phy/rtk/rtl8367s_gsw.ko

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,537 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* $Revision: 76306 $
* $Date: 2017-03-08 15:13:58 +0800 (, 08 2017) $
*
* Purpose : RTK switch high-level API for RTL8367/RTL8367C
* Feature : Here is a list of all functions and variables in CPU module.
*
*/
#include <rtk_switch.h>
#include <rtk_error.h>
#include <cpu.h>
#include <string.h>
#include <rtl8367c_asicdrv.h>
#include <rtl8367c_asicdrv_cputag.h>
/* Function Name:
* rtk_cpu_enable_set
* Description:
* Set CPU port function enable/disable.
* Input:
* enable - CPU port function enable
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameter.
* RT_ERR_PORT_ID - Invalid port number.
* Note:
* The API can set CPU port function enable/disable.
*/
rtk_api_ret_t rtk_cpu_enable_set(rtk_enable_t enable)
{
rtk_api_ret_t retVal;
/* Check initialization state */
RTK_CHK_INIT_STATE();
if (enable >= RTK_ENABLE_END)
return RT_ERR_ENABLE;
if ((retVal = rtl8367c_setAsicCputagEnable(enable)) != RT_ERR_OK)
return retVal;
if (DISABLED == enable)
{
if ((retVal = rtl8367c_setAsicCputagPortmask(0)) != RT_ERR_OK)
return retVal;
}
return RT_ERR_OK;
}
/* Function Name:
* rtk_cpu_enable_get
* Description:
* Get CPU port and its setting.
* Input:
* None
* Output:
* pEnable - CPU port function enable
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_L2_NO_CPU_PORT - CPU port is not exist
* Note:
* The API can get CPU port function enable/disable.
*/
rtk_api_ret_t rtk_cpu_enable_get(rtk_enable_t *pEnable)
{
rtk_api_ret_t retVal;
/* Check initialization state */
RTK_CHK_INIT_STATE();
if(NULL == pEnable)
return RT_ERR_NULL_POINTER;
if ((retVal = rtl8367c_getAsicCputagEnable(pEnable)) != RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}
/* Function Name:
* rtk_cpu_tagPort_set
* Description:
* Set CPU port and CPU tag insert mode.
* Input:
* port - Port id.
* mode - CPU tag insert for packets egress from CPU port.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameter.
* RT_ERR_PORT_ID - Invalid port number.
* Note:
* The API can set CPU port and inserting proprietary CPU tag mode (Length/Type 0x8899)
* to the frame that transmitting to CPU port.
* The inset cpu tag mode is as following:
* - CPU_INSERT_TO_ALL
* - CPU_INSERT_TO_TRAPPING
* - CPU_INSERT_TO_NONE
*/
rtk_api_ret_t rtk_cpu_tagPort_set(rtk_port_t port, rtk_cpu_insert_t mode)
{
rtk_api_ret_t retVal;
/* Check initialization state */
RTK_CHK_INIT_STATE();
/* Check port Valid */
RTK_CHK_PORT_VALID(port);
if (mode >= CPU_INSERT_END)
return RT_ERR_INPUT;
if ((retVal = rtl8367c_setAsicCputagPortmask(1<<rtk_switch_port_L2P_get(port))) != RT_ERR_OK)
return retVal;
if ((retVal = rtl8367c_setAsicCputagTrapPort(rtk_switch_port_L2P_get(port))) != RT_ERR_OK)
return retVal;
if ((retVal = rtl8367c_setAsicCputagInsertMode(mode)) != RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}
/* Function Name:
* rtk_cpu_tagPort_get
* Description:
* Get CPU port and CPU tag insert mode.
* Input:
* None
* Output:
* pPort - Port id.
* pMode - CPU tag insert for packets egress from CPU port, 0:all insert 1:Only for trapped packets 2:no insert.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_L2_NO_CPU_PORT - CPU port is not exist
* Note:
* The API can get configured CPU port and its setting.
* The inset cpu tag mode is as following:
* - CPU_INSERT_TO_ALL
* - CPU_INSERT_TO_TRAPPING
* - CPU_INSERT_TO_NONE
*/
rtk_api_ret_t rtk_cpu_tagPort_get(rtk_port_t *pPort, rtk_cpu_insert_t *pMode)
{
rtk_api_ret_t retVal;
rtk_uint32 pmsk, port;
/* Check initialization state */
RTK_CHK_INIT_STATE();
if(NULL == pPort)
return RT_ERR_NULL_POINTER;
if(NULL == pMode)
return RT_ERR_NULL_POINTER;
if ((retVal = rtl8367c_getAsicCputagPortmask(&pmsk)) != RT_ERR_OK)
return retVal;
if ((retVal = rtl8367c_getAsicCputagTrapPort(&port)) != RT_ERR_OK)
return retVal;
*pPort = rtk_switch_port_P2L_get(port);
if ((retVal = rtl8367c_getAsicCputagInsertMode(pMode)) != RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}
/* Function Name:
* rtk_cpu_awarePort_set
* Description:
* Set CPU aware port mask.
* Input:
* portmask - Port mask.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_MASK - Invalid port mask.
* Note:
* The API can set configured CPU aware port mask.
*/
rtk_api_ret_t rtk_cpu_awarePort_set(rtk_portmask_t *pPortmask)
{
rtk_api_ret_t retVal;
rtk_uint32 phyMbrPmask;
/* Check initialization state */
RTK_CHK_INIT_STATE();
/* Check Valid port mask */
if(NULL == pPortmask)
return RT_ERR_NULL_POINTER;
/* Check port mask valid */
RTK_CHK_PORTMASK_VALID(pPortmask);
if(rtk_switch_portmask_L2P_get(pPortmask, &phyMbrPmask) != RT_ERR_OK)
return RT_ERR_FAILED;
if ((retVal = rtl8367c_setAsicCputagPortmask(phyMbrPmask)) != RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}
/* Function Name:
* rtk_cpu_awarePort_get
* Description:
* Get CPU aware port mask.
* Input:
* None
* Output:
* pPortmask - Port mask.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
* The API can get configured CPU aware port mask.
*/
rtk_api_ret_t rtk_cpu_awarePort_get(rtk_portmask_t *pPortmask)
{
rtk_api_ret_t retVal;
rtk_uint32 pmsk;
/* Check initialization state */
RTK_CHK_INIT_STATE();
if(NULL == pPortmask)
return RT_ERR_NULL_POINTER;
if ((retVal = rtl8367c_getAsicCputagPortmask(&pmsk)) != RT_ERR_OK)
return retVal;
if(rtk_switch_portmask_P2L_get(pmsk, pPortmask) != RT_ERR_OK)
return RT_ERR_FAILED;
return RT_ERR_OK;
}
/* Function Name:
* rtk_cpu_tagPosition_set
* Description:
* Set CPU tag position.
* Input:
* position - CPU tag position.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input.
* Note:
* The API can set CPU tag position.
*/
rtk_api_ret_t rtk_cpu_tagPosition_set(rtk_cpu_position_t position)
{
rtk_api_ret_t retVal;
/* Check initialization state */
RTK_CHK_INIT_STATE();
if (position >= CPU_POS_END)
return RT_ERR_INPUT;
if ((retVal = rtl8367c_setAsicCputagPosition(position)) != RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}
/* Function Name:
* rtk_cpu_tagPosition_get
* Description:
* Get CPU tag position.
* Input:
* None
* Output:
* pPosition - CPU tag position.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input.
* Note:
* The API can get CPU tag position.
*/
rtk_api_ret_t rtk_cpu_tagPosition_get(rtk_cpu_position_t *pPosition)
{
rtk_api_ret_t retVal;
/* Check initialization state */
RTK_CHK_INIT_STATE();
if(NULL == pPosition)
return RT_ERR_NULL_POINTER;
if ((retVal = rtl8367c_getAsicCputagPosition(pPosition)) != RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}
/* Function Name:
* rtk_cpu_tagLength_set
* Description:
* Set CPU tag length.
* Input:
* length - CPU tag length.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input.
* Note:
* The API can set CPU tag length.
*/
rtk_api_ret_t rtk_cpu_tagLength_set(rtk_cpu_tag_length_t length)
{
rtk_api_ret_t retVal;
/* Check initialization state */
RTK_CHK_INIT_STATE();
if (length >= CPU_LEN_END)
return RT_ERR_INPUT;
if ((retVal = rtl8367c_setAsicCputagMode(length)) != RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}
/* Function Name:
* rtk_cpu_tagLength_get
* Description:
* Get CPU tag length.
* Input:
* None
* Output:
* pLength - CPU tag length.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input.
* Note:
* The API can get CPU tag length.
*/
rtk_api_ret_t rtk_cpu_tagLength_get(rtk_cpu_tag_length_t *pLength)
{
rtk_api_ret_t retVal;
/* Check initialization state */
RTK_CHK_INIT_STATE();
if(NULL == pLength)
return RT_ERR_NULL_POINTER;
if ((retVal = rtl8367c_getAsicCputagMode(pLength)) != RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}
/* Function Name:
* rtk_cpu_priRemap_set
* Description:
* Configure CPU priorities mapping to internal absolute priority.
* Input:
* int_pri - internal priority value.
* new_pri - new internal priority value.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_VLAN_PRIORITY - Invalid 1p priority.
* RT_ERR_QOS_INT_PRIORITY - Invalid priority.
* Note:
* Priority of CPU tag assignment for internal asic priority, and it is used for queue usage and packet scheduling.
*/
rtk_api_ret_t rtk_cpu_priRemap_set(rtk_pri_t int_pri, rtk_pri_t new_pri)
{
rtk_api_ret_t retVal;
/* Check initialization state */
RTK_CHK_INIT_STATE();
if (new_pri > RTL8367C_PRIMAX || int_pri > RTL8367C_PRIMAX)
return RT_ERR_VLAN_PRIORITY;
if ((retVal = rtl8367c_setAsicCputagPriorityRemapping(int_pri, new_pri)) != RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}
/* Function Name:
* rtk_cpu_priRemap_get
* Description:
* Configure CPU priorities mapping to internal absolute priority.
* Input:
* int_pri - internal priority value.
* Output:
* pNew_pri - new internal priority value.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_VLAN_PRIORITY - Invalid 1p priority.
* RT_ERR_QOS_INT_PRIORITY - Invalid priority.
* Note:
* Priority of CPU tag assignment for internal asic priority, and it is used for queue usage and packet scheduling.
*/
rtk_api_ret_t rtk_cpu_priRemap_get(rtk_pri_t int_pri, rtk_pri_t *pNew_pri)
{
rtk_api_ret_t retVal;
/* Check initialization state */
RTK_CHK_INIT_STATE();
if(NULL == pNew_pri)
return RT_ERR_NULL_POINTER;
if (int_pri > RTL8367C_PRIMAX)
return RT_ERR_QOS_INT_PRIORITY;
if ((retVal = rtl8367c_getAsicCputagPriorityRemapping(int_pri, pNew_pri)) != RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}
/* Function Name:
* rtk_cpu_acceptLength_set
* Description:
* Set CPU accept length.
* Input:
* length - CPU tag length.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input.
* Note:
* The API can set CPU accept length.
*/
rtk_api_ret_t rtk_cpu_acceptLength_set(rtk_cpu_rx_length_t length)
{
rtk_api_ret_t retVal;
/* Check initialization state */
RTK_CHK_INIT_STATE();
if (length >= CPU_RX_END)
return RT_ERR_INPUT;
if ((retVal = rtl8367c_setAsicCputagRxMinLength(length)) != RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}
/* Function Name:
* rtk_cpu_acceptLength_get
* Description:
* Get CPU accept length.
* Input:
* None
* Output:
* pLength - CPU tag length.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input.
* Note:
* The API can get CPU accept length.
*/
rtk_api_ret_t rtk_cpu_acceptLength_get(rtk_cpu_rx_length_t *pLength)
{
rtk_api_ret_t retVal;
/* Check initialization state */
RTK_CHK_INIT_STATE();
if(NULL == pLength)
return RT_ERR_NULL_POINTER;
if ((retVal = rtl8367c_getAsicCputagRxMinLength(pLength)) != RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}

View file

@ -0,0 +1,843 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* $Revision: 75783 $
* $Date: 2017-02-13 14:54:53 +0800 (, 13 2017) $
*
* Purpose : RTK switch high-level API for RTL8367/RTL8367C
* Feature : Here is a list of all functions and variables in 1X module.
*
*/
#include <rtk_switch.h>
#include <rtk_error.h>
#include <dot1x.h>
#include <string.h>
#include <vlan.h>
#include <rtl8367c_asicdrv.h>
#include <rtl8367c_asicdrv_dot1x.h>
#include <rtl8367c_asicdrv_rma.h>
#include <rtl8367c_asicdrv_lut.h>
#include <rtl8367c_asicdrv_vlan.h>
/* Function Name:
* rtk_dot1x_unauthPacketOper_set
* Description:
* Set 802.1x unauth action configuration.
* Input:
* port - Port id.
* unauth_action - 802.1X unauth action.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_INPUT - Invalid input parameter.
* Note:
* This API can set 802.1x unauth action configuration.
* The unauth action is as following:
* - DOT1X_ACTION_DROP
* - DOT1X_ACTION_TRAP2CPU
* - DOT1X_ACTION_GUESTVLAN
*/
rtk_api_ret_t rtk_dot1x_unauthPacketOper_set(rtk_port_t port, rtk_dot1x_unauth_action_t unauth_action)
{
rtk_api_ret_t retVal;
/* Check initialization state */
RTK_CHK_INIT_STATE();
/* Check port Valid */
RTK_CHK_PORT_VALID(port);
if (unauth_action >= DOT1X_ACTION_END)
return RT_ERR_DOT1X_PROC;
if ((retVal = rtl8367c_setAsic1xProcConfig(rtk_switch_port_L2P_get(port), unauth_action)) != RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}
/* Function Name:
* rtk_dot1x_unauthPacketOper_get
* Description:
* Get 802.1x unauth action configuration.
* Input:
* port - Port id.
* Output:
* pUnauth_action - 802.1X unauth action.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_PORT_ID - Invalid port number.
* Note:
* This API can get 802.1x unauth action configuration.
* The unauth action is as following:
* - DOT1X_ACTION_DROP
* - DOT1X_ACTION_TRAP2CPU
* - DOT1X_ACTION_GUESTVLAN
*/
rtk_api_ret_t rtk_dot1x_unauthPacketOper_get(rtk_port_t port, rtk_dot1x_unauth_action_t *pUnauth_action)
{
rtk_api_ret_t retVal;
/* Check initialization state */
RTK_CHK_INIT_STATE();
/* Check port Valid */
RTK_CHK_PORT_VALID(port);
if(NULL == pUnauth_action)
return RT_ERR_NULL_POINTER;
if ((retVal = rtl8367c_getAsic1xProcConfig(rtk_switch_port_L2P_get(port), pUnauth_action)) != RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}
/* Function Name:
* rtk_dot1x_eapolFrame2CpuEnable_set
* Description:
* Set 802.1x EAPOL packet trap to CPU configuration
* Input:
* enable - The status of 802.1x EAPOL packet.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_ENABLE - Invalid enable input.
* Note:
* To support 802.1x authentication functionality, EAPOL frame (ether type = 0x888E) has to
* be trapped to CPU.
* The status of EAPOL frame trap to CPU is as following:
* - DISABLED
* - ENABLED
*/
rtk_api_ret_t rtk_dot1x_eapolFrame2CpuEnable_set(rtk_enable_t enable)
{
rtk_api_ret_t retVal;
rtl8367c_rma_t rmacfg;
/* Check initialization state */
RTK_CHK_INIT_STATE();
if (enable >= RTK_ENABLE_END)
return RT_ERR_ENABLE;
if ((retVal = rtl8367c_getAsicRma(3, &rmacfg)) != RT_ERR_OK)
return retVal;
if (ENABLED == enable)
rmacfg.operation = RMAOP_TRAP_TO_CPU;
else if (DISABLED == enable)
rmacfg.operation = RMAOP_FORWARD;
if ((retVal = rtl8367c_setAsicRma(3, &rmacfg)) != RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}
/* Function Name:
* rtk_dot1x_eapolFrame2CpuEnable_get
* Description:
* Get 802.1x EAPOL packet trap to CPU configuration
* Input:
* None
* Output:
* pEnable - The status of 802.1x EAPOL packet.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* To support 802.1x authentication functionality, EAPOL frame (ether type = 0x888E) has to
* be trapped to CPU.
* The status of EAPOL frame trap to CPU is as following:
* - DISABLED
* - ENABLED
*/
rtk_api_ret_t rtk_dot1x_eapolFrame2CpuEnable_get(rtk_enable_t *pEnable)
{
rtk_api_ret_t retVal;
rtl8367c_rma_t rmacfg;
/* Check initialization state */
RTK_CHK_INIT_STATE();
if(NULL == pEnable)
return RT_ERR_NULL_POINTER;
if ((retVal = rtl8367c_getAsicRma(3, &rmacfg)) != RT_ERR_OK)
return retVal;
if (RMAOP_TRAP_TO_CPU == rmacfg.operation)
*pEnable = ENABLED;
else
*pEnable = DISABLED;
return RT_ERR_OK;
}
/* Function Name:
* rtk_dot1x_portBasedEnable_set
* Description:
* Set 802.1x port-based enable configuration
* Input:
* port - Port id.
* enable - The status of 802.1x port.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_ENABLE - Invalid enable input.
* RT_ERR_DOT1X_PORTBASEDPNEN - 802.1X port-based enable error
* Note:
* The API can update the port-based port enable register content. If a port is 802.1x
* port based network access control "enabled", it should be authenticated so packets
* from that port won't be dropped or trapped to CPU.
* The status of 802.1x port-based network access control is as following:
* - DISABLED
* - ENABLED
*/
rtk_api_ret_t rtk_dot1x_portBasedEnable_set(rtk_port_t port, rtk_enable_t enable)
{
rtk_api_ret_t retVal;
/* Check initialization state */
RTK_CHK_INIT_STATE();
/* Check port Valid */
RTK_CHK_PORT_VALID(port);
if (enable >= RTK_ENABLE_END)
return RT_ERR_ENABLE;
if ((retVal = rtl8367c_setAsic1xPBEnConfig(rtk_switch_port_L2P_get(port),enable)) != RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}
/* Function Name:
* rtk_dot1x_portBasedEnable_get
* Description:
* Get 802.1x port-based enable configuration
* Input:
* port - Port id.
* Output:
* pEnable - The status of 802.1x port.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_PORT_ID - Invalid port number.
* Note:
* The API can get the 802.1x port-based port status.
*/
rtk_api_ret_t rtk_dot1x_portBasedEnable_get(rtk_port_t port, rtk_enable_t *pEnable)
{
rtk_api_ret_t retVal;
/* Check initialization state */
RTK_CHK_INIT_STATE();
/* Check port Valid */
RTK_CHK_PORT_VALID(port);
if(NULL == pEnable)
return RT_ERR_NULL_POINTER;
if ((retVal = rtl8367c_getAsic1xPBEnConfig(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}
/* Function Name:
* rtk_dot1x_portBasedAuthStatus_set
* Description:
* Set 802.1x port-based auth. port configuration
* Input:
* port - Port id.
* port_auth - The status of 802.1x port.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_DOT1X_PORTBASEDAUTH - 802.1X port-based auth error
* Note:
* The authenticated status of 802.1x port-based network access control is as following:
* - UNAUTH
* - AUTH
*/
rtk_api_ret_t rtk_dot1x_portBasedAuthStatus_set(rtk_port_t port, rtk_dot1x_auth_status_t port_auth)
{
rtk_api_ret_t retVal;
/* Check initialization state */
RTK_CHK_INIT_STATE();
/* Check port Valid */
RTK_CHK_PORT_VALID(port);
if (port_auth >= AUTH_STATUS_END)
return RT_ERR_DOT1X_PORTBASEDAUTH;
if ((retVal = rtl8367c_setAsic1xPBAuthConfig(rtk_switch_port_L2P_get(port), port_auth)) != RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}
/* Function Name:
* rtk_dot1x_portBasedAuthStatus_get
* Description:
* Get 802.1x port-based auth. port configuration
* Input:
* port - Port id.
* Output:
* pPort_auth - The status of 802.1x port.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_PORT_ID - Invalid port number.
* Note:
* The API can get 802.1x port-based port auth.information.
*/
rtk_api_ret_t rtk_dot1x_portBasedAuthStatus_get(rtk_port_t port, rtk_dot1x_auth_status_t *pPort_auth)
{
rtk_api_ret_t retVal;
/* Check initialization state */
RTK_CHK_INIT_STATE();
if(NULL == pPort_auth)
return RT_ERR_NULL_POINTER;
/* Check port Valid */
RTK_CHK_PORT_VALID(port);
if ((retVal = rtl8367c_getAsic1xPBAuthConfig(rtk_switch_port_L2P_get(port), pPort_auth)) != RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}
/* Function Name:
* rtk_dot1x_portBasedDirection_set
* Description:
* Set 802.1x port-based operational direction configuration
* Input:
* port - Port id.
* port_direction - Operation direction
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_DOT1X_PORTBASEDOPDIR - 802.1X port-based operation direction error
* Note:
* The operate controlled direction of 802.1x port-based network access control is as following:
* - BOTH
* - IN
*/
rtk_api_ret_t rtk_dot1x_portBasedDirection_set(rtk_port_t port, rtk_dot1x_direction_t port_direction)
{
rtk_api_ret_t retVal;
/* Check initialization state */
RTK_CHK_INIT_STATE();
/* Check port Valid */
RTK_CHK_PORT_VALID(port);
if (port_direction >= DIRECTION_END)
return RT_ERR_DOT1X_PORTBASEDOPDIR;
if ((retVal = rtl8367c_setAsic1xPBOpdirConfig(rtk_switch_port_L2P_get(port), port_direction)) != RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}
/* Function Name:
* rtk_dot1x_portBasedDirection_get
* Description:
* Get 802.1X port-based operational direction configuration
* Input:
* port - Port id.
* Output:
* pPort_direction - Operation direction
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_PORT_ID - Invalid port number.
* Note:
* The API can get 802.1x port-based operational direction information.
*/
rtk_api_ret_t rtk_dot1x_portBasedDirection_get(rtk_port_t port, rtk_dot1x_direction_t *pPort_direction)
{
rtk_api_ret_t retVal;
/* Check initialization state */
RTK_CHK_INIT_STATE();
if(NULL == pPort_direction)
return RT_ERR_NULL_POINTER;
/* Check port Valid */
RTK_CHK_PORT_VALID(port);
if ((retVal = rtl8367c_getAsic1xPBOpdirConfig(rtk_switch_port_L2P_get(port), pPort_direction)) != RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}
/* Function Name:
* rtk_dot1x_macBasedEnable_set
* Description:
* Set 802.1x mac-based port enable configuration
* Input:
* port - Port id.
* enable - The status of 802.1x port.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_ENABLE - Invalid enable input.
* RT_ERR_DOT1X_MACBASEDPNEN - 802.1X mac-based enable error
* Note:
* If a port is 802.1x MAC based network access control "enabled", the incoming packets should
* be authenticated so packets from that port won't be dropped or trapped to CPU.
* The status of 802.1x MAC-based network access control is as following:
* - DISABLED
* - ENABLED
*/
rtk_api_ret_t rtk_dot1x_macBasedEnable_set(rtk_port_t port, rtk_enable_t enable)
{
rtk_api_ret_t retVal;
/* Check initialization state */
RTK_CHK_INIT_STATE();
/* Check port Valid */
RTK_CHK_PORT_VALID(port);
if (enable >= RTK_ENABLE_END)
return RT_ERR_ENABLE;
if ((retVal = rtl8367c_setAsic1xMBEnConfig(rtk_switch_port_L2P_get(port),enable)) != RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}
/* Function Name:
* rtk_dot1x_macBasedEnable_get
* Description:
* Get 802.1x mac-based port enable configuration
* Input:
* port - Port id.
* Output:
* pEnable - The status of 802.1x port.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_PORT_ID - Invalid port number.
* Note:
* If a port is 802.1x MAC based network access control "enabled", the incoming packets should
* be authenticated so packets from that port wont be dropped or trapped to CPU.
* The status of 802.1x MAC-based network access control is as following:
* - DISABLED
* - ENABLED
*/
rtk_api_ret_t rtk_dot1x_macBasedEnable_get(rtk_port_t port, rtk_enable_t *pEnable)
{
rtk_api_ret_t retVal;
/* Check initialization state */
RTK_CHK_INIT_STATE();
if(NULL == pEnable)
return RT_ERR_NULL_POINTER;
/* Check port Valid */
RTK_CHK_PORT_VALID(port);
if ((retVal = rtl8367c_getAsic1xMBEnConfig(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}
/* Function Name:
* rtk_dot1x_macBasedAuthMac_add
* Description:
* Add an authenticated MAC to ASIC
* Input:
* port - Port id.
* pAuth_mac - The authenticated MAC.
* fid - filtering database.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_ENABLE - Invalid enable input.
* RT_ERR_DOT1X_MACBASEDPNEN - 802.1X mac-based enable error
* Note:
* The API can add a 802.1x authenticated MAC address to port. If the MAC does not exist in LUT,
* user can't add this MAC to auth status.
*/
rtk_api_ret_t rtk_dot1x_macBasedAuthMac_add(rtk_port_t port, rtk_mac_t *pAuth_mac, rtk_fid_t fid)
{
rtk_api_ret_t retVal;
rtk_uint32 method;
rtl8367c_luttb l2Table;
/* Check initialization state */
RTK_CHK_INIT_STATE();
/* must be unicast address */
if ((pAuth_mac == NULL) || (pAuth_mac->octet[0] & 0x1))
return RT_ERR_MAC;
/* Check port Valid */
RTK_CHK_PORT_VALID(port);
if (fid > RTL8367C_FIDMAX)
return RT_ERR_L2_FID;
memset(&l2Table, 0, sizeof(rtl8367c_luttb));
/* fill key (MAC,FID) to get L2 entry */
memcpy(l2Table.mac.octet, pAuth_mac->octet, ETHER_ADDR_LEN);
l2Table.fid = fid;
method = LUTREADMETHOD_MAC;
retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table);
if ( RT_ERR_OK == retVal)
{
if (l2Table.spa != rtk_switch_port_L2P_get(port))
return RT_ERR_DOT1X_MAC_PORT_MISMATCH;
memcpy(l2Table.mac.octet, pAuth_mac->octet, ETHER_ADDR_LEN);
l2Table.fid = fid;
l2Table.efid = 0;
l2Table.auth = 1;
retVal = rtl8367c_setAsicL2LookupTb(&l2Table);
return retVal;
}
else
return retVal;
}
/* Function Name:
* rtk_dot1x_macBasedAuthMac_del
* Description:
* Delete an authenticated MAC to ASIC
* Input:
* port - Port id.
* pAuth_mac - The authenticated MAC.
* fid - filtering database.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_MAC - Invalid MAC address.
* RT_ERR_PORT_ID - Invalid port number.
* Note:
* The API can delete a 802.1x authenticated MAC address to port. It only change the auth status of
* the MAC and won't delete it from LUT.
*/
rtk_api_ret_t rtk_dot1x_macBasedAuthMac_del(rtk_port_t port, rtk_mac_t *pAuth_mac, rtk_fid_t fid)
{
rtk_api_ret_t retVal;
rtk_uint32 method;
rtl8367c_luttb l2Table;
/* Check initialization state */
RTK_CHK_INIT_STATE();
/* must be unicast address */
if ((pAuth_mac == NULL) || (pAuth_mac->octet[0] & 0x1))
return RT_ERR_MAC;
/* Check port Valid */
RTK_CHK_PORT_VALID(port);
if (fid > RTL8367C_FIDMAX)
return RT_ERR_L2_FID;
memset(&l2Table, 0, sizeof(rtl8367c_luttb));
/* fill key (MAC,FID) to get L2 entry */
memcpy(l2Table.mac.octet, pAuth_mac->octet, ETHER_ADDR_LEN);
l2Table.fid = fid;
method = LUTREADMETHOD_MAC;
retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table);
if (RT_ERR_OK == retVal)
{
if (l2Table.spa != rtk_switch_port_L2P_get(port))
return RT_ERR_DOT1X_MAC_PORT_MISMATCH;
memcpy(l2Table.mac.octet, pAuth_mac->octet, ETHER_ADDR_LEN);
l2Table.fid = fid;
l2Table.auth = 0;
retVal = rtl8367c_setAsicL2LookupTb(&l2Table);
return retVal;
}
else
return retVal;
}
/* Function Name:
* rtk_dot1x_macBasedDirection_set
* Description:
* Set 802.1x mac-based operational direction configuration
* Input:
* mac_direction - Operation direction
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameter.
* RT_ERR_DOT1X_MACBASEDOPDIR - 802.1X mac-based operation direction error
* Note:
* The operate controlled direction of 802.1x mac-based network access control is as following:
* - BOTH
* - IN
*/
rtk_api_ret_t rtk_dot1x_macBasedDirection_set(rtk_dot1x_direction_t mac_direction)
{
rtk_api_ret_t retVal;
/* Check initialization state */
RTK_CHK_INIT_STATE();
if (mac_direction >= DIRECTION_END)
return RT_ERR_DOT1X_MACBASEDOPDIR;
if ((retVal = rtl8367c_setAsic1xMBOpdirConfig(mac_direction)) != RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}
/* Function Name:
* rtk_dot1x_macBasedDirection_get
* Description:
* Get 802.1x mac-based operational direction configuration
* Input:
* port - Port id.
* Output:
* pMac_direction - Operation direction
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The API can get 802.1x mac-based operational direction information.
*/
rtk_api_ret_t rtk_dot1x_macBasedDirection_get(rtk_dot1x_direction_t *pMac_direction)
{
rtk_api_ret_t retVal;
/* Check initialization state */
RTK_CHK_INIT_STATE();
if(NULL == pMac_direction)
return RT_ERR_NULL_POINTER;
if ((retVal = rtl8367c_getAsic1xMBOpdirConfig(pMac_direction)) != RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}
/* Function Name:
* Set 802.1x guest VLAN configuration
* Description:
* Set 802.1x mac-based operational direction configuration
* Input:
* vid - 802.1x guest VLAN ID
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameter.
* Note:
* The operate controlled 802.1x guest VLAN
*/
rtk_api_ret_t rtk_dot1x_guestVlan_set(rtk_vlan_t vid)
{
rtk_api_ret_t retVal;
rtk_uint32 index;
/* Check initialization state */
RTK_CHK_INIT_STATE();
/* vid must be 0~4095 */
if (vid > RTL8367C_VIDMAX)
return RT_ERR_VLAN_VID;
if((retVal = rtk_vlan_checkAndCreateMbr(vid, &index)) != RT_ERR_OK)
return retVal;
if ((retVal = rtl8367c_setAsic1xGuestVidx(index)) != RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}
/* Function Name:
* rtk_dot1x_guestVlan_get
* Description:
* Get 802.1x guest VLAN configuration
* Input:
* None
* Output:
* pVid - 802.1x guest VLAN ID
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The API can get 802.1x guest VLAN information.
*/
rtk_api_ret_t rtk_dot1x_guestVlan_get(rtk_vlan_t *pVid)
{
rtk_api_ret_t retVal;
rtk_uint32 gvidx;
rtl8367c_vlanconfiguser vlanMC;
/* Check initialization state */
RTK_CHK_INIT_STATE();
if(NULL == pVid)
return RT_ERR_NULL_POINTER;
if ((retVal = rtl8367c_getAsic1xGuestVidx(&gvidx)) != RT_ERR_OK)
return retVal;
if ((retVal = rtl8367c_getAsicVlanMemberConfig(gvidx, &vlanMC)) != RT_ERR_OK)
return retVal;
*pVid = vlanMC.evid;
return RT_ERR_OK;
}
/* Function Name:
* rtk_dot1x_guestVlan2Auth_set
* Description:
* Set 802.1x guest VLAN to auth host configuration
* Input:
* enable - The status of guest VLAN to auth host.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameter.
* Note:
* The operational direction of 802.1x guest VLAN to auth host control is as following:
* - ENABLED
* - DISABLED
*/
rtk_api_ret_t rtk_dot1x_guestVlan2Auth_set(rtk_enable_t enable)
{
rtk_api_ret_t retVal;
/* Check initialization state */
RTK_CHK_INIT_STATE();
if (enable >= RTK_ENABLE_END)
return RT_ERR_ENABLE;
if ((retVal = rtl8367c_setAsic1xGVOpdir(enable)) != RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}
/* Function Name:
* rtk_dot1x_guestVlan2Auth_get
* Description:
* Get 802.1x guest VLAN to auth host configuration
* Input:
* None
* Output:
* pEnable - The status of guest VLAN to auth host.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The API can get 802.1x guest VLAN to auth host information.
*/
rtk_api_ret_t rtk_dot1x_guestVlan2Auth_get(rtk_enable_t *pEnable)
{
rtk_api_ret_t retVal;
/* Check initialization state */
RTK_CHK_INIT_STATE();
if(NULL == pEnable)
return RT_ERR_NULL_POINTER;
if ((retVal = rtl8367c_getAsic1xGVOpdir(pEnable)) != RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}

View file

@ -0,0 +1,162 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* $Revision: 48156 $
* $Date: 2014-05-29 16:39:06 +0800 (, 29 2014) $
*
* Purpose : RTK switch high-level API for RTL8367/RTL8367C
* Feature : Here is a list of all functions and variables in EEE module.
*
*/
#include <rtk_switch.h>
#include <rtk_error.h>
#include <eee.h>
#include <string.h>
#include <rtl8367c_asicdrv.h>
#include <rtl8367c_asicdrv_eee.h>
#include <rtl8367c_asicdrv_phy.h>
/* Function Name:
* rtk_eee_init
* Description:
* EEE function initialization.
* Input:
* None
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
* This API is used to initialize EEE status.
*/
rtk_api_ret_t rtk_eee_init(void)
{
rtk_api_ret_t retVal;
/* Check initialization state */
RTK_CHK_INIT_STATE();
if((retVal = rtl8367c_setAsicRegBit(0x0018, 10, 1)) != RT_ERR_OK)
return retVal;
if((retVal = rtl8367c_setAsicRegBit(0x0018, 11, 1)) != RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}
/* Function Name:
* rtk_eee_portEnable_set
* Description:
* Set enable status of EEE function.
* Input:
* port - port id.
* enable - enable EEE status.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_ENABLE - Invalid enable input.
* Note:
* This API can set EEE function to the specific port.
* The configuration of the port is as following:
* - DISABLE
* - ENABLE
*/
rtk_api_ret_t rtk_eee_portEnable_set(rtk_port_t port, rtk_enable_t enable)
{
rtk_api_ret_t retVal;
rtk_uint32 regData;
rtk_uint32 phy_port;
/* Check initialization state */
RTK_CHK_INIT_STATE();
/* Check port is UTP port */
RTK_CHK_PORT_IS_UTP(port);
if (enable>=RTK_ENABLE_END)
return RT_ERR_INPUT;
phy_port = rtk_switch_port_L2P_get(port);
if ((retVal = rtl8367c_setAsicEee100M(phy_port,enable))!=RT_ERR_OK)
return retVal;
if ((retVal = rtl8367c_setAsicEeeGiga(phy_port,enable))!=RT_ERR_OK)
return retVal;
if ((retVal = rtl8367c_setAsicPHYReg(phy_port, RTL8367C_PHY_PAGE_ADDRESS, 0))!=RT_ERR_OK)
return retVal;
if ((retVal = rtl8367c_getAsicPHYReg(phy_port, 0, &regData))!=RT_ERR_OK)
return retVal;
regData |= 0x0200;
if ((retVal = rtl8367c_setAsicPHYReg(phy_port, 0, regData))!=RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}
/* Function Name:
* rtk_eee_portEnable_get
* Description:
* Get enable status of EEE function
* Input:
* port - Port id.
* Output:
* pEnable - Back pressure status.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* Note:
* This API can get EEE function to the specific port.
* The configuration of the port is as following:
* - DISABLE
* - ENABLE
*/
rtk_api_ret_t rtk_eee_portEnable_get(rtk_port_t port, rtk_enable_t *pEnable)
{
rtk_api_ret_t retVal;
rtk_uint32 regData1, regData2;
rtk_uint32 phy_port;
/* Check initialization state */
RTK_CHK_INIT_STATE();
/* Check port is UTP port */
RTK_CHK_PORT_IS_UTP(port);
if(NULL == pEnable)
return RT_ERR_NULL_POINTER;
phy_port = rtk_switch_port_L2P_get(port);
if ((retVal = rtl8367c_getAsicEee100M(phy_port,&regData1))!=RT_ERR_OK)
return retVal;
if ((retVal = rtl8367c_getAsicEeeGiga(phy_port,&regData2))!=RT_ERR_OK)
return retVal;
if (regData1==1&&regData2==1)
*pEnable = ENABLED;
else
*pEnable = DISABLED;
return RT_ERR_OK;
}

View file

@ -0,0 +1,436 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* $Revision: 63932 $
* $Date: 2015-12-08 14:06:29 +0800 (, 08 2015) $
*
* Purpose : RTK switch high-level API for RTL8367/RTL8367C
* Feature : Here is a list of all functions and variables in i2c module.
*
*/
#include <rtk_switch.h>
#include <rtk_error.h>
#include <port.h>
#include <string.h>
#include <rtl8367c_reg.h>
#include <rtl8367c_asicdrv_i2c.h>
#include <rtk_switch.h>
#include <rtl8367c_asicdrv.h>
#include <rtk_types.h>
#include <i2c.h>
static rtk_I2C_16bit_mode_t rtk_i2c_mode = I2C_LSB_16BIT_MODE;
/* Function Name:
* rtk_i2c_init
* Description:
* I2C smart function initialization.
* Input:
* None
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* Note:
* This API is used to initialize EEE status.
* need used GPIO pins
* OpenDrain and clock
*/
rtk_api_ret_t rtk_i2c_init(void)
{
rtk_uint32 retVal;
switch_chip_t ChipID;
/* probe switch */
if((retVal = rtk_switch_probe(&ChipID)) != RT_ERR_OK)
return retVal;
if( ChipID == CHIP_RTL8370B )
{
/*set GPIO8, GPIO9, OpenDrain as I2C, clock = 252KHZ */
if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_SYS_CTL, 0x5c3f)) != RT_ERR_OK)
return retVal;
}
else
return RT_ERR_FAILED;
return RT_ERR_OK;
}
/* Function Name:
* rtk_i2c_mode_set
* Description:
* Set I2C data byte-order.
* Input:
* i2cmode - byte-order mode
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_INPUT - Invalid input parameter.
* Note:
* This API can set I2c traffic's byte-order .
*/
rtk_api_ret_t rtk_i2c_mode_set( rtk_I2C_16bit_mode_t i2cmode )
{
if(i2cmode >= I2C_Mode_END)
{
return RT_ERR_INPUT;
}
else if(i2cmode == I2C_70B_LSB_16BIT_MODE)
{
rtk_i2c_mode = I2C_70B_LSB_16BIT_MODE;
return RT_ERR_OK;
}
else if( i2cmode == I2C_LSB_16BIT_MODE)
{
rtk_i2c_mode = I2C_LSB_16BIT_MODE;
return RT_ERR_OK;
}
else
return RT_ERR_FAILED;
return RT_ERR_OK;
}
/* Function Name:
* rtk_i2c_mode_get
* Description:
* Get i2c traffic byte-order setting.
* Input:
* None
* Output:
* pI2cMode - i2c byte-order
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_NULL_POINTER - input parameter is null pointer
* Note:
* The API can get i2c traffic byte-order setting.
*/
rtk_api_ret_t rtk_i2c_mode_get( rtk_I2C_16bit_mode_t * pI2cMode)
{
/* Check initialization state */
RTK_CHK_INIT_STATE();
if(NULL == pI2cMode)
return RT_ERR_NULL_POINTER;
if(rtk_i2c_mode == I2C_70B_LSB_16BIT_MODE)
*pI2cMode = 1;
else if ((rtk_i2c_mode == I2C_LSB_16BIT_MODE))
*pI2cMode = 0;
else
return RT_ERR_FAILED;
return RT_ERR_OK;
}
/* Function Name:
* rtk_i2c_gpioPinGroup_set
* Description:
* Set i2c SDA & SCL used GPIO pins group.
* Input:
* pins_group - GPIO pins group
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_INPUT - Invalid input parameter.
* Note:
* The API can set i2c used gpio pins group.
* There are three group pins could be used
*/
rtk_api_ret_t rtk_i2c_gpioPinGroup_set( rtk_I2C_gpio_pin_t pins_group )
{
rtk_uint32 retVal;
if( ( pins_group > I2C_GPIO_PIN_END )|| ( pins_group < I2C_GPIO_PIN_8_9) )
return RT_ERR_INPUT;
if( (retVal = rtl8367c_setAsicI2CGpioPinGroup(pins_group) ) != RT_ERR_OK )
return retVal ;
return RT_ERR_OK;
}
/* Function Name:
* rtk_i2c_gpioPinGroup_get
* Description:
* Get i2c SDA & SCL used GPIO pins group.
* Input:
* None
* Output:
* pPins_group - GPIO pins group
* Return:
* RT_ERR_OK - OK
* RT_ERR_NULL_POINTER - input parameter is null pointer
* Note:
* The API can get i2c used gpio pins group.
* There are three group pins could be used
*/
rtk_api_ret_t rtk_i2c_gpioPinGroup_get( rtk_I2C_gpio_pin_t * pPins_group )
{
rtk_uint32 retVal;
/* Check initialization state */
RTK_CHK_INIT_STATE();
if(NULL == pPins_group)
return RT_ERR_NULL_POINTER;
if( (retVal = rtl8367c_getAsicI2CGpioPinGroup(pPins_group) ) != RT_ERR_OK )
return retVal;
return RT_ERR_OK;
}
/* Function Name:
* rtk_i2c_data_read
* Description:
* read i2c slave device register.
* Input:
* deviceAddr - access Slave device address
* slaveRegAddr - access Slave register address
* Output:
* pRegData - read data
* Return:
* RT_ERR_OK - OK
* RT_ERR_NULL_POINTER - input parameter is null pointer
* Note:
* The API can access i2c slave and read i2c slave device register.
*/
rtk_api_ret_t rtk_i2c_data_read(rtk_uint8 deviceAddr, rtk_uint32 slaveRegAddr, rtk_uint32 *pRegData)
{
rtk_uint32 retVal, counter=0;
rtk_uint8 controlByte_W, controlByte_R;
rtk_uint8 slaveRegAddr_L, slaveRegAddr_H = 0x0, temp;
rtk_uint8 regData_L, regData_H;
/* control byte :deviceAddress + W, deviceAddress + R */
controlByte_W = (rtk_uint8)(deviceAddr << 1) ;
controlByte_R = (rtk_uint8)(controlByte_W | 0x1);
slaveRegAddr_L = (rtk_uint8) (slaveRegAddr & 0x00FF) ;
slaveRegAddr_H = (rtk_uint8) (slaveRegAddr >>8) ;
if( rtk_i2c_mode == I2C_70B_LSB_16BIT_MODE)
{
temp = slaveRegAddr_L ;
slaveRegAddr_L = slaveRegAddr_H;
slaveRegAddr_H = temp;
}
/*check bus state: idle*/
for(counter = 3000; counter>0; counter--)
{
if ( (retVal = rtl8367c_setAsicI2C_checkBusIdle() ) == RT_ERR_OK)
break;
}
if( counter ==0 )
return retVal; /*i2c is busy*/
/*tx Start cmd*/
if( (retVal = rtl8367c_setAsicI2CStartCmd() ) != RT_ERR_OK )
return retVal ;
/*tx control _W*/
if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(controlByte_W))!= RT_ERR_OK )
return retVal ;
/*check if RX ack from slave*/
if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK )
return retVal;
/* tx slave buffer address low 8 bits */
if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(slaveRegAddr_L))!= RT_ERR_OK )
return retVal ;
/*check if RX ack from slave*/
if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK )
return retVal;
/* tx slave buffer address high 8 bits */
if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(slaveRegAddr_H))!= RT_ERR_OK )
return retVal ;
/*check if RX ack from slave*/
if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK )
return retVal;
/*tx Start cmd*/
if( (retVal = rtl8367c_setAsicI2CStartCmd() ) != RT_ERR_OK )
return retVal ;
/*tx control _R*/
if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(controlByte_R))!= RT_ERR_OK )
return retVal ;
/*check if RX ack from slave*/
if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK )
return retVal;
/* rx low 8bit data*/
if( ( retVal = rtl8367c_setAsicI2CRxOneCharCmd( &regData_L) ) != RT_ERR_OK )
return retVal;
/* tx ack to slave, keep receive */
if( (retVal = rtl8367c_setAsicI2CTxAckCmd()) != RT_ERR_OK )
return retVal;
/* rx high 8bit data*/
if( ( retVal = rtl8367c_setAsicI2CRxOneCharCmd( &regData_H) ) != RT_ERR_OK )
return retVal;
/* tx Noack to slave, Stop receive */
if( (retVal = rtl8367c_setAsicI2CTxNoAckCmd()) != RT_ERR_OK )
return retVal;
/*tx Stop cmd */
if( (retVal = rtl8367c_setAsicI2CStopCmd()) != RT_ERR_OK )
return retVal;
*pRegData = (regData_H << 8) | regData_L;
return RT_ERR_OK;
}
/* Function Name:
* rtk_i2c_data_write
* Description:
* write data to i2c slave device register
* Input:
* deviceAddr - access Slave device address
* slaveRegAddr - access Slave register address
* regData - data to set
* Output:
* None
* Return:
* RT_ERR_OK - OK
* Note:
* The API can access i2c slave and setting i2c slave device register.
*/
rtk_api_ret_t rtk_i2c_data_write(rtk_uint8 deviceAddr, rtk_uint32 slaveRegAddr, rtk_uint32 regData)
{
rtk_uint32 retVal,counter;
rtk_uint8 controlByte_W;
rtk_uint8 slaveRegAddr_L, slaveRegAddr_H = 0x0, temp;
rtk_uint8 regData_L, regData_H;
/* control byte :deviceAddress + W */
controlByte_W = (rtk_uint8)(deviceAddr<< 1) ;
slaveRegAddr_L = (rtk_uint8) (slaveRegAddr & 0x00FF) ;
slaveRegAddr_H = (rtk_uint8) (slaveRegAddr >>8) ;
regData_H = (rtk_uint8) (regData>> 8);
regData_L = (rtk_uint8) (regData & 0x00FF);
if( rtk_i2c_mode == I2C_70B_LSB_16BIT_MODE)
{
temp = slaveRegAddr_L ;
slaveRegAddr_L = slaveRegAddr_H;
slaveRegAddr_H = temp;
}
/*check bus state: idle*/
for(counter = 3000; counter>0; counter--)
{
if ( (retVal = rtl8367c_setAsicI2C_checkBusIdle() ) == RT_ERR_OK)
break;
}
if( counter ==0 )
return retVal; /*i2c is busy*/
/*tx Start cmd*/
if( (retVal = rtl8367c_setAsicI2CStartCmd() ) != RT_ERR_OK )
return retVal ;
/*tx control _W*/
if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(controlByte_W))!= RT_ERR_OK )
return retVal ;
/*check if RX ack from slave*/
if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK )
return retVal;
/* tx slave buffer address low 8 bits */
if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(slaveRegAddr_L))!= RT_ERR_OK )
return retVal;
/*check if RX ack from slave*/
if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK )
return retVal;
/* tx slave buffer address high 8 bits */
if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(slaveRegAddr_H))!= RT_ERR_OK )
return retVal;
/*check if RX ack from slave*/
if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK )
return retVal;
/*tx Datavlue LSB*/
if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(regData_L))!= RT_ERR_OK )
return retVal;
/*check if RX ack from slave*/
if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK )
return retVal;
/*tx Datavlue MSB*/
if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(regData_H))!= RT_ERR_OK )
return retVal;
/*check if RX ack from slave*/
if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK )
return retVal;
/*tx Stop cmd */
if( (retVal = rtl8367c_setAsicI2CStopCmd()) != RT_ERR_OK )
return retVal;
return RT_ERR_OK;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,990 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* Purpose : RTL8367/RTL8367C switch high-level API
*
* Feature : The file includes ACL module high-layer API defination
*
*/
#ifndef __RTK_API_ACL_H__
#define __RTK_API_ACL_H__
/*
* Data Type Declaration
*/
#define RTK_FILTER_RAW_FIELD_NUMBER 8
#define ACL_DEFAULT_ABILITY 0
#define ACL_DEFAULT_UNMATCH_PERMIT 1
#define ACL_RULE_FREE 0
#define ACL_RULE_INAVAILABLE 1
#define ACL_RULE_CARETAG_MASK 0x1F
#define FILTER_POLICING_MAX 4
#define FILTER_LOGGING_MAX 8
#define FILTER_PATTERN_MAX 4
#define FILTER_ENACT_CVLAN_MASK 0x01
#define FILTER_ENACT_SVLAN_MASK 0x02
#define FILTER_ENACT_PRIORITY_MASK 0x04
#define FILTER_ENACT_POLICING_MASK 0x08
#define FILTER_ENACT_FWD_MASK 0x10
#define FILTER_ENACT_INTGPIO_MASK 0x20
#define FILTER_ENACT_INIT_MASK 0x3F
typedef enum rtk_filter_act_cactext_e
{
FILTER_ENACT_CACTEXT_VLANONLY=0,
FILTER_ENACT_CACTEXT_BOTHVLANTAG,
FILTER_ENACT_CACTEXT_TAGONLY,
FILTER_ENACT_CACTEXT_END,
}rtk_filter_act_cactext_t;
typedef enum rtk_filter_act_ctagfmt_e
{
FILTER_CTAGFMT_UNTAG=0,
FILTER_CTAGFMT_TAG,
FILTER_CTAGFMT_KEEP,
FILTER_CTAGFMT_KEEP1PRMK,
}rtk_filter_act_ctag_t;
#define RTK_MAX_NUM_OF_FILTER_TYPE 5
#define RTK_MAX_NUM_OF_FILTER_FIELD 8
#define RTK_DOT_1AS_TIMESTAMP_UNIT_IN_WORD_LENGTH 3UL
#define RTK_IPV6_ADDR_WORD_LENGTH 4UL
#define FILTER_ENACT_CVLAN_TYPE(type) (type - FILTER_ENACT_CVLAN_INGRESS)
#define FILTER_ENACT_SVLAN_TYPE(type) (type - FILTER_ENACT_SVLAN_INGRESS)
#define FILTER_ENACT_FWD_TYPE(type) (type - FILTER_ENACT_ADD_DSTPORT)
#define FILTER_ENACT_PRI_TYPE(type) (type - FILTER_ENACT_PRIORITY)
#define RTK_FILTER_FIELD_USED_MAX 8
#define RTK_FILTER_FIELD_INDEX(template, index) ((template << 4) + index)
typedef enum rtk_filter_act_enable_e
{
/* CVLAN */
FILTER_ENACT_CVLAN_INGRESS = 0,
FILTER_ENACT_CVLAN_EGRESS,
FILTER_ENACT_CVLAN_SVID,
FILTER_ENACT_POLICING_1,
/* SVLAN */
FILTER_ENACT_SVLAN_INGRESS,
FILTER_ENACT_SVLAN_EGRESS,
FILTER_ENACT_SVLAN_CVID,
FILTER_ENACT_POLICING_2,
/* Policing and Logging */
FILTER_ENACT_POLICING_0,
/* Forward */
FILTER_ENACT_COPY_CPU,
FILTER_ENACT_DROP,
FILTER_ENACT_ADD_DSTPORT,
FILTER_ENACT_REDIRECT,
FILTER_ENACT_MIRROR,
FILTER_ENACT_TRAP_CPU,
FILTER_ENACT_ISOLATION,
/* QoS */
FILTER_ENACT_PRIORITY,
FILTER_ENACT_DSCP_REMARK,
FILTER_ENACT_1P_REMARK,
FILTER_ENACT_POLICING_3,
/* Interrutp and GPO */
FILTER_ENACT_INTERRUPT,
FILTER_ENACT_GPO,
/*VLAN tag*/
FILTER_ENACT_EGRESSCTAG_UNTAG,
FILTER_ENACT_EGRESSCTAG_TAG,
FILTER_ENACT_EGRESSCTAG_KEEP,
FILTER_ENACT_EGRESSCTAG_KEEPAND1PRMK,
FILTER_ENACT_END,
} rtk_filter_act_enable_t;
typedef struct
{
rtk_filter_act_enable_t actEnable[FILTER_ENACT_END];
/* CVLAN acton */
rtk_uint32 filterCvlanVid;
rtk_uint32 filterCvlanIdx;
/* SVLAN action */
rtk_uint32 filterSvlanVid;
rtk_uint32 filterSvlanIdx;
/* Policing action */
rtk_uint32 filterPolicingIdx[FILTER_POLICING_MAX];
/* Forwarding action */
rtk_portmask_t filterPortmask;
/* QOS action */
rtk_uint32 filterPriority;
/*GPO*/
rtk_uint32 filterPin;
} rtk_filter_action_t;
typedef struct rtk_filter_flag_s
{
rtk_uint32 value;
rtk_uint32 mask;
} rtk_filter_flag_t;
typedef enum rtk_filter_care_tag_index_e
{
CARE_TAG_CTAG = 0,
CARE_TAG_STAG,
CARE_TAG_PPPOE,
CARE_TAG_IPV4,
CARE_TAG_IPV6,
CARE_TAG_TCP,
CARE_TAG_UDP,
CARE_TAG_ARP,
CARE_TAG_RSV1,
CARE_TAG_RSV2,
CARE_TAG_ICMP,
CARE_TAG_IGMP,
CARE_TAG_LLC,
CARE_TAG_RSV3,
CARE_TAG_HTTP,
CARE_TAG_RSV4,
CARE_TAG_RSV5,
CARE_TAG_DHCP,
CARE_TAG_DHCPV6,
CARE_TAG_SNMP,
CARE_TAG_OAM,
CARE_TAG_END,
} rtk_filter_care_tag_index_t;
typedef struct rtk_filter_care_tag_s
{
rtk_filter_flag_t tagType[CARE_TAG_END];
} rtk_filter_care_tag_t;
typedef struct rtk_filter_field rtk_filter_field_t;
typedef struct
{
rtk_uint32 value[RTK_DOT_1AS_TIMESTAMP_UNIT_IN_WORD_LENGTH];
} rtk_filter_dot1as_timestamp_t;
typedef enum rtk_filter_field_data_type_e
{
FILTER_FIELD_DATA_MASK = 0,
FILTER_FIELD_DATA_RANGE,
FILTER_FIELD_DATA_END ,
} rtk_filter_field_data_type_t;
typedef struct rtk_filter_ip_s
{
rtk_uint32 dataType;
rtk_uint32 rangeStart;
rtk_uint32 rangeEnd;
rtk_uint32 value;
rtk_uint32 mask;
} rtk_filter_ip_t;
typedef struct rtk_filter_mac_s
{
rtk_uint32 dataType;
rtk_mac_t value;
rtk_mac_t mask;
rtk_mac_t rangeStart;
rtk_mac_t rangeEnd;
} rtk_filter_mac_t;
typedef rtk_uint32 rtk_filter_op_t;
typedef struct rtk_filter_value_s
{
rtk_uint32 dataType;
rtk_uint32 value;
rtk_uint32 mask;
rtk_uint32 rangeStart;
rtk_uint32 rangeEnd;
} rtk_filter_value_t;
typedef struct rtk_filter_activeport_s
{
rtk_portmask_t value;
rtk_portmask_t mask;
} rtk_filter_activeport_t;
typedef struct rtk_filter_tag_s
{
rtk_filter_value_t pri;
rtk_filter_flag_t cfi;
rtk_filter_value_t vid;
} rtk_filter_tag_t;
typedef struct rtk_filter_ipFlag_s
{
rtk_filter_flag_t xf;
rtk_filter_flag_t mf;
rtk_filter_flag_t df;
} rtk_filter_ipFlag_t;
typedef struct
{
rtk_uint32 addr[RTK_IPV6_ADDR_WORD_LENGTH];
} rtk_filter_ip6_addr_t;
typedef struct
{
rtk_uint32 dataType;
rtk_filter_ip6_addr_t value;
rtk_filter_ip6_addr_t mask;
rtk_filter_ip6_addr_t rangeStart;
rtk_filter_ip6_addr_t rangeEnd;
} rtk_filter_ip6_t;
typedef rtk_uint32 rtk_filter_number_t;
typedef struct rtk_filter_pattern_s
{
rtk_uint32 value[FILTER_PATTERN_MAX];
rtk_uint32 mask[FILTER_PATTERN_MAX];
} rtk_filter_pattern_t;
typedef struct rtk_filter_tcpFlag_s
{
rtk_filter_flag_t urg;
rtk_filter_flag_t ack;
rtk_filter_flag_t psh;
rtk_filter_flag_t rst;
rtk_filter_flag_t syn;
rtk_filter_flag_t fin;
rtk_filter_flag_t ns;
rtk_filter_flag_t cwr;
rtk_filter_flag_t ece;
} rtk_filter_tcpFlag_t;
typedef rtk_uint32 rtk_filter_field_raw_t;
typedef enum rtk_filter_field_temple_input_e
{
FILTER_FIELD_TEMPLE_INPUT_TYPE = 0,
FILTER_FIELD_TEMPLE_INPUT_INDEX,
FILTER_FIELD_TEMPLE_INPUT_MAX ,
} rtk_filter_field_temple_input_t;
struct rtk_filter_field
{
rtk_uint32 fieldType;
union
{
/* L2 struct */
rtk_filter_mac_t dmac;
rtk_filter_mac_t smac;
rtk_filter_value_t etherType;
rtk_filter_tag_t ctag;
rtk_filter_tag_t relayCtag;
rtk_filter_tag_t stag;
rtk_filter_tag_t l2tag;
rtk_filter_dot1as_timestamp_t dot1asTimeStamp;
rtk_filter_mac_t mac;
/* L3 struct */
rtk_filter_ip_t sip;
rtk_filter_ip_t dip;
rtk_filter_ip_t ip;
rtk_filter_value_t protocol;
rtk_filter_value_t ipTos;
rtk_filter_ipFlag_t ipFlag;
rtk_filter_value_t ipOffset;
rtk_filter_ip6_t sipv6;
rtk_filter_ip6_t dipv6;
rtk_filter_ip6_t ipv6;
rtk_filter_value_t ipv6TrafficClass;
rtk_filter_value_t ipv6NextHeader;
rtk_filter_value_t flowLabel;
/* L4 struct */
rtk_filter_value_t tcpSrcPort;
rtk_filter_value_t tcpDstPort;
rtk_filter_tcpFlag_t tcpFlag;
rtk_filter_value_t tcpSeqNumber;
rtk_filter_value_t tcpAckNumber;
rtk_filter_value_t udpSrcPort;
rtk_filter_value_t udpDstPort;
rtk_filter_value_t icmpCode;
rtk_filter_value_t icmpType;
rtk_filter_value_t igmpType;
/* pattern match */
rtk_filter_pattern_t pattern;
rtk_filter_value_t inData;
} filter_pattern_union;
rtk_uint32 fieldTemplateNo;
rtk_uint32 fieldTemplateIdx[RTK_FILTER_FIELD_USED_MAX];
struct rtk_filter_field *next;
};
typedef enum rtk_filter_field_type_e
{
FILTER_FIELD_DMAC = 0,
FILTER_FIELD_SMAC,
FILTER_FIELD_ETHERTYPE,
FILTER_FIELD_CTAG,
FILTER_FIELD_STAG,
FILTER_FIELD_IPV4_SIP,
FILTER_FIELD_IPV4_DIP,
FILTER_FIELD_IPV4_TOS,
FILTER_FIELD_IPV4_PROTOCOL,
FILTER_FIELD_IPV4_FLAG,
FILTER_FIELD_IPV4_OFFSET,
FILTER_FIELD_IPV6_SIPV6,
FILTER_FIELD_IPV6_DIPV6,
FILTER_FIELD_IPV6_TRAFFIC_CLASS,
FILTER_FIELD_IPV6_NEXT_HEADER,
FILTER_FIELD_TCP_SPORT,
FILTER_FIELD_TCP_DPORT,
FILTER_FIELD_TCP_FLAG,
FILTER_FIELD_UDP_SPORT,
FILTER_FIELD_UDP_DPORT,
FILTER_FIELD_ICMP_CODE,
FILTER_FIELD_ICMP_TYPE,
FILTER_FIELD_IGMP_TYPE,
FILTER_FIELD_VID_RANGE,
FILTER_FIELD_IP_RANGE,
FILTER_FIELD_PORT_RANGE,
FILTER_FIELD_USER_DEFINED00,
FILTER_FIELD_USER_DEFINED01,
FILTER_FIELD_USER_DEFINED02,
FILTER_FIELD_USER_DEFINED03,
FILTER_FIELD_USER_DEFINED04,
FILTER_FIELD_USER_DEFINED05,
FILTER_FIELD_USER_DEFINED06,
FILTER_FIELD_USER_DEFINED07,
FILTER_FIELD_USER_DEFINED08,
FILTER_FIELD_USER_DEFINED09,
FILTER_FIELD_USER_DEFINED10,
FILTER_FIELD_USER_DEFINED11,
FILTER_FIELD_USER_DEFINED12,
FILTER_FIELD_USER_DEFINED13,
FILTER_FIELD_USER_DEFINED14,
FILTER_FIELD_USER_DEFINED15,
FILTER_FIELD_PATTERN_MATCH,
FILTER_FIELD_END,
} rtk_filter_field_type_t;
typedef enum rtk_filter_field_type_raw_e
{
FILTER_FIELD_RAW_UNUSED = 0,
FILTER_FIELD_RAW_DMAC_15_0,
FILTER_FIELD_RAW_DMAC_31_16,
FILTER_FIELD_RAW_DMAC_47_32,
FILTER_FIELD_RAW_SMAC_15_0,
FILTER_FIELD_RAW_SMAC_31_16,
FILTER_FIELD_RAW_SMAC_47_32,
FILTER_FIELD_RAW_ETHERTYPE,
FILTER_FIELD_RAW_STAG,
FILTER_FIELD_RAW_CTAG,
FILTER_FIELD_RAW_IPV4_SIP_15_0 = 0x10,
FILTER_FIELD_RAW_IPV4_SIP_31_16,
FILTER_FIELD_RAW_IPV4_DIP_15_0,
FILTER_FIELD_RAW_IPV4_DIP_31_16,
FILTER_FIELD_RAW_IPV6_SIP_15_0 = 0x20,
FILTER_FIELD_RAW_IPV6_SIP_31_16,
FILTER_FIELD_RAW_IPV6_DIP_15_0 = 0x28,
FILTER_FIELD_RAW_IPV6_DIP_31_16,
FILTER_FIELD_RAW_VIDRANGE = 0x30,
FILTER_FIELD_RAW_IPRANGE,
FILTER_FIELD_RAW_PORTRANGE,
FILTER_FIELD_RAW_FIELD_VALID,
FILTER_FIELD_RAW_FIELD_SELECT00 = 0x40,
FILTER_FIELD_RAW_FIELD_SELECT01,
FILTER_FIELD_RAW_FIELD_SELECT02,
FILTER_FIELD_RAW_FIELD_SELECT03,
FILTER_FIELD_RAW_FIELD_SELECT04,
FILTER_FIELD_RAW_FIELD_SELECT05,
FILTER_FIELD_RAW_FIELD_SELECT06,
FILTER_FIELD_RAW_FIELD_SELECT07,
FILTER_FIELD_RAW_FIELD_SELECT08,
FILTER_FIELD_RAW_FIELD_SELECT09,
FILTER_FIELD_RAW_FIELD_SELECT10,
FILTER_FIELD_RAW_FIELD_SELECT11,
FILTER_FIELD_RAW_FIELD_SELECT12,
FILTER_FIELD_RAW_FIELD_SELECT13,
FILTER_FIELD_RAW_FIELD_SELECT14,
FILTER_FIELD_RAW_FIELD_SELECT15,
FILTER_FIELD_RAW_END,
} rtk_filter_field_type_raw_t;
typedef enum rtk_filter_flag_care_type_e
{
FILTER_FLAG_CARE_DONT_CARE = 0,
FILTER_FLAG_CARE_1,
FILTER_FLAG_CARE_0,
FILTER_FLAG_END
} rtk_filter_flag_care_type_t;
typedef rtk_uint32 rtk_filter_id_t; /* filter id type */
typedef enum rtk_filter_invert_e
{
FILTER_INVERT_DISABLE = 0,
FILTER_INVERT_ENABLE,
FILTER_INVERT_END,
} rtk_filter_invert_t;
typedef rtk_uint32 rtk_filter_state_t;
typedef rtk_uint32 rtk_filter_unmatch_action_t;
typedef enum rtk_filter_unmatch_action_e
{
FILTER_UNMATCH_DROP = 0,
FILTER_UNMATCH_PERMIT,
FILTER_UNMATCH_END,
} rtk_filter_unmatch_action_type_t;
typedef struct
{
rtk_filter_field_t *fieldHead;
rtk_filter_care_tag_t careTag;
rtk_filter_activeport_t activeport;
rtk_filter_invert_t invert;
} rtk_filter_cfg_t;
typedef struct
{
rtk_filter_field_raw_t dataFieldRaw[RTK_FILTER_RAW_FIELD_NUMBER];
rtk_filter_field_raw_t careFieldRaw[RTK_FILTER_RAW_FIELD_NUMBER];
rtk_filter_field_type_raw_t fieldRawType[RTK_FILTER_RAW_FIELD_NUMBER];
rtk_filter_care_tag_t careTag;
rtk_filter_activeport_t activeport;
rtk_filter_invert_t invert;
rtk_enable_t valid;
} rtk_filter_cfg_raw_t;
typedef struct
{
rtk_uint32 index;
rtk_filter_field_type_raw_t fieldType[RTK_FILTER_RAW_FIELD_NUMBER];
} rtk_filter_template_t;
typedef enum rtk_field_sel_e
{
FORMAT_DEFAULT = 0,
FORMAT_RAW,
FORMAT_LLC,
FORMAT_IPV4,
FORMAT_ARP,
FORMAT_IPV6,
FORMAT_IPPAYLOAD,
FORMAT_L4PAYLOAD,
FORMAT_END
}rtk_field_sel_t;
typedef enum rtk_filter_iprange_e
{
IPRANGE_UNUSED = 0,
IPRANGE_IPV4_SIP,
IPRANGE_IPV4_DIP,
IPRANGE_IPV6_SIP,
IPRANGE_IPV6_DIP,
IPRANGE_END
}rtk_filter_iprange_t;
typedef enum rtk_filter_vidrange_e
{
VIDRANGE_UNUSED = 0,
VIDRANGE_CVID,
VIDRANGE_SVID,
VIDRANGE_END
}rtk_filter_vidrange_t;
typedef enum rtk_filter_portrange_e
{
PORTRANGE_UNUSED = 0,
PORTRANGE_SPORT,
PORTRANGE_DPORT,
PORTRANGE_END
}rtk_filter_portrange_t;
/* Function Name:
* rtk_filter_igrAcl_init
* Description:
* ACL initialization function
* Input:
* None
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_NULL_POINTER - Pointer pFilter_field or pFilter_cfg point to NULL.
* Note:
* This function enable and intialize ACL function
*/
extern rtk_api_ret_t rtk_filter_igrAcl_init(void);
/* Function Name:
* rtk_filter_igrAcl_field_add
* Description:
* Add comparison rule to an ACL configuration
* Input:
* pFilter_cfg - The ACL configuration that this function will add comparison rule
* pFilter_field - The comparison rule that will be added.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_NULL_POINTER - Pointer pFilter_field or pFilter_cfg point to NULL.
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* This function add a comparison rule (*pFilter_field) to an ACL configuration (*pFilter_cfg).
* Pointer pFilter_cfg points to an ACL configuration structure, this structure keeps multiple ACL
* comparison rules by means of linked list. Pointer pFilter_field will be added to linked
* list keeped by structure that pFilter_cfg points to.
*/
extern rtk_api_ret_t rtk_filter_igrAcl_field_add(rtk_filter_cfg_t *pFilter_cfg, rtk_filter_field_t *pFilter_field);
/* Function Name:
* rtk_filter_igrAcl_cfg_add
* Description:
* Add an ACL configuration to ASIC
* Input:
* filter_id - Start index of ACL configuration.
* pFilter_cfg - The ACL configuration that this function will add comparison rule
* pFilter_action - Action(s) of ACL configuration.
* Output:
* ruleNum - number of rules written in acl table
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_NULL_POINTER - Pointer pFilter_field or pFilter_cfg point to NULL.
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_ENTRY_INDEX - Invalid filter_id .
* RT_ERR_NULL_POINTER - Pointer pFilter_action or pFilter_cfg point to NULL.
* RT_ERR_FILTER_INACL_ACT_NOT_SUPPORT - Action is not supported in this chip.
* RT_ERR_FILTER_INACL_RULE_NOT_SUPPORT - Rule is not supported.
* Note:
* This function store pFilter_cfg, pFilter_action into ASIC. The starting
* index(es) is filter_id.
*/
extern rtk_api_ret_t rtk_filter_igrAcl_cfg_add(rtk_filter_id_t filter_id, rtk_filter_cfg_t *pFilter_cfg, rtk_filter_action_t *pAction, rtk_filter_number_t *ruleNum);
/* Function Name:
* rtk_filter_igrAcl_cfg_del
* Description:
* Delete an ACL configuration from ASIC
* Input:
* filter_id - Start index of ACL configuration.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_FILTER_ENTRYIDX - Invalid filter_id.
* Note:
* This function delete a group of ACL rules starting from filter_id.
*/
extern rtk_api_ret_t rtk_filter_igrAcl_cfg_del(rtk_filter_id_t filter_id);
/* Function Name:
* rtk_filter_igrAcl_cfg_delAll
* Description:
* Delete all ACL entries from ASIC
* Input:
* None
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
* This function delete all ACL configuration from ASIC.
*/
extern rtk_api_ret_t rtk_filter_igrAcl_cfg_delAll(void);
/* Function Name:
* rtk_filter_igrAcl_cfg_get
* Description:
* Get one ingress acl configuration from ASIC.
* Input:
* filter_id - Start index of ACL configuration.
* Output:
* pFilter_cfg - buffer pointer of ingress acl data
* pFilter_action - buffer pointer of ingress acl action
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_NULL_POINTER - Pointer pFilter_action or pFilter_cfg point to NULL.
* RT_ERR_FILTER_ENTRYIDX - Invalid entry index.
* Note:
* This function delete all ACL configuration from ASIC.
*/
extern rtk_api_ret_t rtk_filter_igrAcl_cfg_get(rtk_filter_id_t filter_id, rtk_filter_cfg_raw_t *pFilter_cfg, rtk_filter_action_t *pAction);
/* Function Name:
* rtk_filter_igrAcl_unmatchAction_set
* Description:
* Set action to packets when no ACL configuration match
* Input:
* port - Port id.
* action - Action.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port id.
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* This function sets action of packets when no ACL configruation matches.
*/
extern rtk_api_ret_t rtk_filter_igrAcl_unmatchAction_set(rtk_port_t port, rtk_filter_unmatch_action_t action);
/* Function Name:
* rtk_filter_igrAcl_unmatchAction_get
* Description:
* Get action to packets when no ACL configuration match
* Input:
* port - Port id.
* Output:
* pAction - Action.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port id.
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* This function gets action of packets when no ACL configruation matches.
*/
extern rtk_api_ret_t rtk_filter_igrAcl_unmatchAction_get(rtk_port_t port, rtk_filter_unmatch_action_t* action);
/* Function Name:
* rtk_filter_igrAcl_state_set
* Description:
* Set state of ingress ACL.
* Input:
* port - Port id.
* state - Ingress ACL state.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port id.
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* This function gets action of packets when no ACL configruation matches.
*/
extern rtk_api_ret_t rtk_filter_igrAcl_state_set(rtk_port_t port, rtk_filter_state_t state);
/* Function Name:
* rtk_filter_igrAcl_state_get
* Description:
* Get state of ingress ACL.
* Input:
* port - Port id.
* Output:
* pState - Ingress ACL state.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port id.
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* This function gets action of packets when no ACL configruation matches.
*/
extern rtk_api_ret_t rtk_filter_igrAcl_state_get(rtk_port_t port, rtk_filter_state_t* state);
/* Function Name:
* rtk_filter_igrAcl_template_set
* Description:
* Set template of ingress ACL.
* Input:
* template - Ingress ACL template
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* This function set ACL template.
*/
extern rtk_api_ret_t rtk_filter_igrAcl_template_set(rtk_filter_template_t *aclTemplate);
/* Function Name:
* rtk_filter_igrAcl_template_get
* Description:
* Get template of ingress ACL.
* Input:
* template - Ingress ACL template
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
* This function gets template of ACL.
*/
extern rtk_api_ret_t rtk_filter_igrAcl_template_get(rtk_filter_template_t *aclTemplate);
/* Function Name:
* rtk_filter_igrAcl_field_sel_set
* Description:
* Set user defined field selectors in HSB
* Input:
* index - index of field selector 0-15
* format - Format of field selector
* offset - Retrieving data offset
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
* System support 16 user defined field selctors.
* Each selector can be enabled or disable.
* User can defined retrieving 16-bits in many predefiend
* standard l2/l3/l4 payload.
*/
extern rtk_api_ret_t rtk_filter_igrAcl_field_sel_set(rtk_uint32 index, rtk_field_sel_t format, rtk_uint32 offset);
/* Function Name:
* rtk_filter_igrAcl_field_sel_get
* Description:
* Get user defined field selectors in HSB
* Input:
* index - index of field selector 0-15
* Output:
* pFormat - Format of field selector
* pOffset - Retrieving data offset
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
* None.
*/
extern rtk_api_ret_t rtk_filter_igrAcl_field_sel_get(rtk_uint32 index, rtk_field_sel_t *pFormat, rtk_uint32 *pOffset);
/* Function Name:
* rtk_filter_iprange_set
* Description:
* Set IP Range check
* Input:
* index - index of IP Range 0-15
* type - IP Range check type, 0:Delete a entry, 1: IPv4_SIP, 2: IPv4_DIP, 3:IPv6_SIP, 4:IPv6_DIP
* upperIp - The upper bound of IP range
* lowerIp - The lower Bound of IP range
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_OUT_OF_RANGE - The parameter is out of range
* RT_ERR_INPUT - Input error
* Note:
* upperIp must be larger or equal than lowerIp.
*/
extern rtk_api_ret_t rtk_filter_iprange_set(rtk_uint32 index, rtk_filter_iprange_t type, ipaddr_t upperIp, ipaddr_t lowerIp);
/* Function Name:
* rtk_filter_iprange_get
* Description:
* Set IP Range check
* Input:
* index - index of IP Range 0-15
* Output:
* pType - IP Range check type, 0:Delete a entry, 1: IPv4_SIP, 2: IPv4_DIP, 3:IPv6_SIP, 4:IPv6_DIP
* pUpperIp - The upper bound of IP range
* pLowerIp - The lower Bound of IP range
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_OUT_OF_RANGE - The parameter is out of range
* Note:
* upperIp must be larger or equal than lowerIp.
*/
extern rtk_api_ret_t rtk_filter_iprange_get(rtk_uint32 index, rtk_filter_iprange_t *pType, ipaddr_t *pUpperIp, ipaddr_t *pLowerIp);
/* Function Name:
* rtk_filter_vidrange_set
* Description:
* Set VID Range check
* Input:
* index - index of VID Range 0-15
* type - IP Range check type, 0:Delete a entry, 1: CVID, 2: SVID
* upperVid - The upper bound of VID range
* lowerVid - The lower Bound of VID range
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_OUT_OF_RANGE - The parameter is out of range
* RT_ERR_INPUT - Input error
* Note:
* upperVid must be larger or equal than lowerVid.
*/
extern rtk_api_ret_t rtk_filter_vidrange_set(rtk_uint32 index, rtk_filter_vidrange_t type, rtk_uint32 upperVid, rtk_uint32 lowerVid);
/* Function Name:
* rtk_filter_vidrange_get
* Description:
* Get VID Range check
* Input:
* index - index of VID Range 0-15
* Output:
* pType - IP Range check type, 0:Unused, 1: CVID, 2: SVID
* pUpperVid - The upper bound of VID range
* pLowerVid - The lower Bound of VID range
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_OUT_OF_RANGE - The parameter is out of range
* Note:
* None.
*/
extern rtk_api_ret_t rtk_filter_vidrange_get(rtk_uint32 index, rtk_filter_vidrange_t *pType, rtk_uint32 *pUpperVid, rtk_uint32 *pLowerVid);
/* Function Name:
* rtk_filter_portrange_set
* Description:
* Set Port Range check
* Input:
* index - index of Port Range 0-15
* type - IP Range check type, 0:Delete a entry, 1: Source Port, 2: Destnation Port
* upperPort - The upper bound of Port range
* lowerPort - The lower Bound of Port range
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_OUT_OF_RANGE - The parameter is out of range
* RT_ERR_INPUT - Input error
* Note:
* upperPort must be larger or equal than lowerPort.
*/
extern rtk_api_ret_t rtk_filter_portrange_set(rtk_uint32 index, rtk_filter_portrange_t type, rtk_uint32 upperPort, rtk_uint32 lowerPort);
/* Function Name:
* rtk_filter_portrange_get
* Description:
* Set Port Range check
* Input:
* index - index of Port Range 0-15
* Output:
* pType - IP Range check type, 0:Delete a entry, 1: Source Port, 2: Destnation Port
* pUpperPort - The upper bound of Port range
* pLowerPort - The lower Bound of Port range
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_OUT_OF_RANGE - The parameter is out of range
* RT_ERR_INPUT - Input error
* Note:
* None.
*/
extern rtk_api_ret_t rtk_filter_portrange_get(rtk_uint32 index, rtk_filter_portrange_t *pType, rtk_uint32 *pUpperPort, rtk_uint32 *pLowerPort);
/* Function Name:
* rtk_filter_igrAclPolarity_set
* Description:
* Set ACL Goip control palarity
* Input:
* polarity - 1: High, 0: Low
* Output:
* None
* Return:
* RT_ERR_OK - Success
* RT_ERR_SMI - SMI access error
* Note:
* none
*/
extern rtk_api_ret_t rtk_filter_igrAclPolarity_set(rtk_uint32 polarity);
/* Function Name:
* rtk_filter_igrAclPolarity_get
* Description:
* Get ACL Goip control palarity
* Input:
* pPolarity - 1: High, 0: Low
* Output:
* None
* Return:
* RT_ERR_OK - Success
* RT_ERR_SMI - SMI access error
* Note:
* none
*/
extern rtk_api_ret_t rtk_filter_igrAclPolarity_get(rtk_uint32* pPolarity);
#endif /* __RTK_API_ACL_H__ */

View file

@ -0,0 +1,327 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* Purpose : RTL8367/RTL8367C switch high-level API
*
* Feature : The file includes CPU module high-layer API defination
*
*/
#ifndef __RTK_API_CPU_H__
#define __RTK_API_CPU_H__
/*
* Data Type Declaration
*/
typedef enum rtk_cpu_insert_e
{
CPU_INSERT_TO_ALL = 0,
CPU_INSERT_TO_TRAPPING,
CPU_INSERT_TO_NONE,
CPU_INSERT_END
}rtk_cpu_insert_t;
typedef enum rtk_cpu_position_e
{
CPU_POS_AFTER_SA = 0,
CPU_POS_BEFORE_CRC,
CPU_POS_END
}rtk_cpu_position_t;
typedef enum rtk_cpu_tag_length_e
{
CPU_LEN_8BYTES = 0,
CPU_LEN_4BYTES,
CPU_LEN_END
}rtk_cpu_tag_length_t;
typedef enum rtk_cpu_rx_length_e
{
CPU_RX_72BYTES = 0,
CPU_RX_64BYTES,
CPU_RX_END
}rtk_cpu_rx_length_t;
/* Function Name:
* rtk_cpu_enable_set
* Description:
* Set CPU port function enable/disable.
* Input:
* enable - CPU port function enable
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameter.
* RT_ERR_PORT_ID - Invalid port number.
* Note:
* The API can set CPU port function enable/disable.
*/
extern rtk_api_ret_t rtk_cpu_enable_set(rtk_enable_t enable);
/* Function Name:
* rtk_cpu_enable_get
* Description:
* Get CPU port and its setting.
* Input:
* None
* Output:
* pEnable - CPU port function enable
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_L2_NO_CPU_PORT - CPU port is not exist
* Note:
* The API can get CPU port function enable/disable.
*/
extern rtk_api_ret_t rtk_cpu_enable_get(rtk_enable_t *pEnable);
/* Function Name:
* rtk_cpu_tagPort_set
* Description:
* Set CPU port and CPU tag insert mode.
* Input:
* port - Port id.
* mode - CPU tag insert for packets egress from CPU port.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameter.
* RT_ERR_PORT_ID - Invalid port number.
* Note:
* The API can set CPU port and inserting proprietary CPU tag mode (Length/Type 0x8899)
* to the frame that transmitting to CPU port.
* The inset cpu tag mode is as following:
* - CPU_INSERT_TO_ALL
* - CPU_INSERT_TO_TRAPPING
* - CPU_INSERT_TO_NONE
*/
extern rtk_api_ret_t rtk_cpu_tagPort_set(rtk_port_t port, rtk_cpu_insert_t mode);
/* Function Name:
* rtk_cpu_tagPort_get
* Description:
* Get CPU port and CPU tag insert mode.
* Input:
* None
* Output:
* pPort - Port id.
* pMode - CPU tag insert for packets egress from CPU port, 0:all insert 1:Only for trapped packets 2:no insert.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_L2_NO_CPU_PORT - CPU port is not exist
* Note:
* The API can get configured CPU port and its setting.
* The inset cpu tag mode is as following:
* - CPU_INSERT_TO_ALL
* - CPU_INSERT_TO_TRAPPING
* - CPU_INSERT_TO_NONE
*/
extern rtk_api_ret_t rtk_cpu_tagPort_get(rtk_port_t *pPort, rtk_cpu_insert_t *pMode);
/* Function Name:
* rtk_cpu_awarePort_set
* Description:
* Set CPU aware port mask.
* Input:
* portmask - Port mask.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_MASK - Invalid port mask.
* Note:
* The API can set configured CPU aware port mask.
*/
extern rtk_api_ret_t rtk_cpu_awarePort_set(rtk_portmask_t *pPortmask);
/* Function Name:
* rtk_cpu_awarePort_get
* Description:
* Get CPU aware port mask.
* Input:
* None
* Output:
* pPortmask - Port mask.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
* The API can get configured CPU aware port mask.
*/
extern rtk_api_ret_t rtk_cpu_awarePort_get(rtk_portmask_t *pPortmask);
/* Function Name:
* rtk_cpu_tagPosition_set
* Description:
* Set CPU tag position.
* Input:
* position - CPU tag position.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input.
* Note:
* The API can set CPU tag position.
*/
extern rtk_api_ret_t rtk_cpu_tagPosition_set(rtk_cpu_position_t position);
/* Function Name:
* rtk_cpu_tagPosition_get
* Description:
* Get CPU tag position.
* Input:
* None
* Output:
* pPosition - CPU tag position.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input.
* Note:
* The API can get CPU tag position.
*/
extern rtk_api_ret_t rtk_cpu_tagPosition_get(rtk_cpu_position_t *pPosition);
/* Function Name:
* rtk_cpu_tagLength_set
* Description:
* Set CPU tag length.
* Input:
* length - CPU tag length.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input.
* Note:
* The API can set CPU tag length.
*/
extern rtk_api_ret_t rtk_cpu_tagLength_set(rtk_cpu_tag_length_t length);
/* Function Name:
* rtk_cpu_tagLength_get
* Description:
* Get CPU tag length.
* Input:
* None
* Output:
* pLength - CPU tag length.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input.
* Note:
* The API can get CPU tag length.
*/
extern rtk_api_ret_t rtk_cpu_tagLength_get(rtk_cpu_tag_length_t *pLength);
/* Function Name:
* rtk_cpu_acceptLength_set
* Description:
* Set CPU accept length.
* Input:
* length - CPU tag length.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input.
* Note:
* The API can set CPU accept length.
*/
extern rtk_api_ret_t rtk_cpu_acceptLength_set(rtk_cpu_rx_length_t length);
/* Function Name:
* rtk_cpu_acceptLength_get
* Description:
* Get CPU accept length.
* Input:
* None
* Output:
* pLength - CPU tag length.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input.
* Note:
* The API can get CPU accept length.
*/
extern rtk_api_ret_t rtk_cpu_acceptLength_get(rtk_cpu_rx_length_t *pLength);
/* Function Name:
* rtk_cpu_priRemap_set
* Description:
* Configure CPU priorities mapping to internal absolute priority.
* Input:
* int_pri - internal priority value.
* new_pri - new internal priority value.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_VLAN_PRIORITY - Invalid 1p priority.
* RT_ERR_QOS_INT_PRIORITY - Invalid priority.
* Note:
* Priority of CPU tag assignment for internal asic priority, and it is used for queue usage and packet scheduling.
*/
extern rtk_api_ret_t rtk_cpu_priRemap_set(rtk_pri_t int_pri, rtk_pri_t new_pri);
/* Function Name:
* rtk_cpu_priRemap_get
* Description:
* Configure CPU priorities mapping to internal absolute priority.
* Input:
* int_pri - internal priority value.
* Output:
* pNew_pri - new internal priority value.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_VLAN_PRIORITY - Invalid 1p priority.
* RT_ERR_QOS_INT_PRIORITY - Invalid priority.
* Note:
* Priority of CPU tag assignment for internal asic priority, and it is used for queue usage and packet scheduling.
*/
extern rtk_api_ret_t rtk_cpu_priRemap_get(rtk_pri_t int_pri, rtk_pri_t *pNew_pri);
#endif /* __RTK_API_CPU_H__ */

View file

@ -0,0 +1,470 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* Purpose : RTL8367/RTL8367C switch high-level API
*
* Feature : The file includes 1X module high-layer API defination
*
*/
#ifndef __RTK_API_DOT1X_H__
#define __RTK_API_DOT1X_H__
/* Type of port-based dot1x auth/unauth*/
typedef enum rtk_dot1x_auth_status_e
{
UNAUTH = 0,
AUTH,
AUTH_STATUS_END
} rtk_dot1x_auth_status_t;
typedef enum rtk_dot1x_direction_e
{
DIR_BOTH = 0,
DIR_IN,
DIRECTION_END
} rtk_dot1x_direction_t;
/* unauth pkt action */
typedef enum rtk_dot1x_unauth_action_e
{
DOT1X_ACTION_DROP = 0,
DOT1X_ACTION_TRAP2CPU,
DOT1X_ACTION_GUESTVLAN,
DOT1X_ACTION_END
} rtk_dot1x_unauth_action_t;
/* Function Name:
* rtk_dot1x_unauthPacketOper_set
* Description:
* Set 802.1x unauth action configuration.
* Input:
* port - Port id.
* unauth_action - 802.1X unauth action.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_INPUT - Invalid input parameter.
* Note:
* This API can set 802.1x unauth action configuration.
* The unauth action is as following:
* - DOT1X_ACTION_DROP
* - DOT1X_ACTION_TRAP2CPU
* - DOT1X_ACTION_GUESTVLAN
*/
extern rtk_api_ret_t rtk_dot1x_unauthPacketOper_set(rtk_port_t port, rtk_dot1x_unauth_action_t unauth_action);
/* Function Name:
* rtk_dot1x_unauthPacketOper_get
* Description:
* Get 802.1x unauth action configuration.
* Input:
* port - Port id.
* Output:
* pUnauth_action - 802.1X unauth action.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_PORT_ID - Invalid port number.
* Note:
* This API can get 802.1x unauth action configuration.
* The unauth action is as following:
* - DOT1X_ACTION_DROP
* - DOT1X_ACTION_TRAP2CPU
* - DOT1X_ACTION_GUESTVLAN
*/
extern rtk_api_ret_t rtk_dot1x_unauthPacketOper_get(rtk_port_t port, rtk_dot1x_unauth_action_t *pUnauth_action);
/* Function Name:
* rtk_dot1x_eapolFrame2CpuEnable_set
* Description:
* Set 802.1x EAPOL packet trap to CPU configuration
* Input:
* enable - The status of 802.1x EAPOL packet.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_ENABLE - Invalid enable input.
* Note:
* To support 802.1x authentication functionality, EAPOL frame (ether type = 0x888E) has to
* be trapped to CPU.
* The status of EAPOL frame trap to CPU is as following:
* - DISABLED
* - ENABLED
*/
extern rtk_api_ret_t rtk_dot1x_eapolFrame2CpuEnable_set(rtk_enable_t enable);
/* Function Name:
* rtk_dot1x_eapolFrame2CpuEnable_get
* Description:
* Get 802.1x EAPOL packet trap to CPU configuration
* Input:
* None
* Output:
* pEnable - The status of 802.1x EAPOL packet.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* To support 802.1x authentication functionality, EAPOL frame (ether type = 0x888E) has to
* be trapped to CPU.
* The status of EAPOL frame trap to CPU is as following:
* - DISABLED
* - ENABLED
*/
extern rtk_api_ret_t rtk_dot1x_eapolFrame2CpuEnable_get(rtk_enable_t *pEnable);
/* Function Name:
* rtk_dot1x_portBasedEnable_set
* Description:
* Set 802.1x port-based enable configuration
* Input:
* port - Port id.
* enable - The status of 802.1x port.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_ENABLE - Invalid enable input.
* RT_ERR_DOT1X_PORTBASEDPNEN - 802.1X port-based enable error
* Note:
* The API can update the port-based port enable register content. If a port is 802.1x
* port based network access control "enabled", it should be authenticated so packets
* from that port won't be dropped or trapped to CPU.
* The status of 802.1x port-based network access control is as following:
* - DISABLED
* - ENABLED
*/
extern rtk_api_ret_t rtk_dot1x_portBasedEnable_set(rtk_port_t port, rtk_enable_t enable);
/* Function Name:
* rtk_dot1x_portBasedEnable_get
* Description:
* Get 802.1x port-based enable configuration
* Input:
* port - Port id.
* Output:
* pEnable - The status of 802.1x port.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_PORT_ID - Invalid port number.
* Note:
* The API can get the 802.1x port-based port status.
*/
extern rtk_api_ret_t rtk_dot1x_portBasedEnable_get(rtk_port_t port, rtk_enable_t *pEnable);
/* Function Name:
* rtk_dot1x_portBasedAuthStatus_set
* Description:
* Set 802.1x port-based auth. port configuration
* Input:
* port - Port id.
* port_auth - The status of 802.1x port.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_DOT1X_PORTBASEDAUTH - 802.1X port-based auth error
* Note:
* The authenticated status of 802.1x port-based network access control is as following:
* - UNAUTH
* - AUTH
*/
extern rtk_api_ret_t rtk_dot1x_portBasedAuthStatus_set(rtk_port_t port, rtk_dot1x_auth_status_t port_auth);
/* Function Name:
* rtk_dot1x_portBasedAuthStatus_get
* Description:
* Get 802.1x port-based auth. port configuration
* Input:
* port - Port id.
* Output:
* pPort_auth - The status of 802.1x port.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_PORT_ID - Invalid port number.
* Note:
* The API can get 802.1x port-based port auth.information.
*/
extern rtk_api_ret_t rtk_dot1x_portBasedAuthStatus_get(rtk_port_t port, rtk_dot1x_auth_status_t *pPort_auth);
/* Function Name:
* rtk_dot1x_portBasedDirection_set
* Description:
* Set 802.1x port-based operational direction configuration
* Input:
* port - Port id.
* port_direction - Operation direction
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_DOT1X_PORTBASEDOPDIR - 802.1X port-based operation direction error
* Note:
* The operate controlled direction of 802.1x port-based network access control is as following:
* - BOTH
* - IN
*/
extern rtk_api_ret_t rtk_dot1x_portBasedDirection_set(rtk_port_t port, rtk_dot1x_direction_t port_direction);
/* Function Name:
* rtk_dot1x_portBasedDirection_get
* Description:
* Get 802.1X port-based operational direction configuration
* Input:
* port - Port id.
* Output:
* pPort_direction - Operation direction
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_PORT_ID - Invalid port number.
* Note:
* The API can get 802.1x port-based operational direction information.
*/
extern rtk_api_ret_t rtk_dot1x_portBasedDirection_get(rtk_port_t port, rtk_dot1x_direction_t *pPort_direction);
/* Function Name:
* rtk_dot1x_macBasedEnable_set
* Description:
* Set 802.1x mac-based port enable configuration
* Input:
* port - Port id.
* enable - The status of 802.1x port.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_ENABLE - Invalid enable input.
* RT_ERR_DOT1X_MACBASEDPNEN - 802.1X mac-based enable error
* Note:
* If a port is 802.1x MAC based network access control "enabled", the incoming packets should
* be authenticated so packets from that port won't be dropped or trapped to CPU.
* The status of 802.1x MAC-based network access control is as following:
* - DISABLED
* - ENABLED
*/
extern rtk_api_ret_t rtk_dot1x_macBasedEnable_set(rtk_port_t port, rtk_enable_t enable);
/* Function Name:
* rtk_dot1x_macBasedEnable_get
* Description:
* Get 802.1x mac-based port enable configuration
* Input:
* port - Port id.
* Output:
* pEnable - The status of 802.1x port.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_PORT_ID - Invalid port number.
* Note:
* If a port is 802.1x MAC based network access control "enabled", the incoming packets should
* be authenticated so packets from that port wont be dropped or trapped to CPU.
* The status of 802.1x MAC-based network access control is as following:
* - DISABLED
* - ENABLED
*/
extern rtk_api_ret_t rtk_dot1x_macBasedEnable_get(rtk_port_t port, rtk_enable_t *pEnable);
/* Function Name:
* rtk_dot1x_macBasedAuthMac_add
* Description:
* Add an authenticated MAC to ASIC
* Input:
* port - Port id.
* pAuth_mac - The authenticated MAC.
* fid - filtering database.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_ENABLE - Invalid enable input.
* RT_ERR_DOT1X_MACBASEDPNEN - 802.1X mac-based enable error
* Note:
* The API can add a 802.1x authenticated MAC address to port. If the MAC does not exist in LUT,
* user can't add this MAC to auth status.
*/
extern rtk_api_ret_t rtk_dot1x_macBasedAuthMac_add(rtk_port_t port, rtk_mac_t *pAuth_mac, rtk_fid_t fid);
/* Function Name:
* rtk_dot1x_macBasedAuthMac_del
* Description:
* Delete an authenticated MAC to ASIC
* Input:
* port - Port id.
* pAuth_mac - The authenticated MAC.
* fid - filtering database.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_MAC - Invalid MAC address.
* RT_ERR_PORT_ID - Invalid port number.
* Note:
* The API can delete a 802.1x authenticated MAC address to port. It only change the auth status of
* the MAC and won't delete it from LUT.
*/
extern rtk_api_ret_t rtk_dot1x_macBasedAuthMac_del(rtk_port_t port, rtk_mac_t *pAuth_mac, rtk_fid_t fid);
/* Function Name:
* rtk_dot1x_macBasedDirection_set
* Description:
* Set 802.1x mac-based operational direction configuration
* Input:
* mac_direction - Operation direction
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameter.
* RT_ERR_DOT1X_MACBASEDOPDIR - 802.1X mac-based operation direction error
* Note:
* The operate controlled direction of 802.1x mac-based network access control is as following:
* - BOTH
* - IN
*/
extern rtk_api_ret_t rtk_dot1x_macBasedDirection_set(rtk_dot1x_direction_t mac_direction);
/* Function Name:
* rtk_dot1x_macBasedDirection_get
* Description:
* Get 802.1x mac-based operational direction configuration
* Input:
* port - Port id.
* Output:
* pMac_direction - Operation direction
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The API can get 802.1x mac-based operational direction information.
*/
extern rtk_api_ret_t rtk_dot1x_macBasedDirection_get(rtk_dot1x_direction_t *pMac_direction);
/* Function Name:
* Set 802.1x guest VLAN configuration
* Description:
* Set 802.1x mac-based operational direction configuration
* Input:
* vid - 802.1x guest VLAN ID
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameter.
* Note:
* The operate controlled 802.1x guest VLAN
*/
extern rtk_api_ret_t rtk_dot1x_guestVlan_set(rtk_vlan_t vid);
/* Function Name:
* rtk_dot1x_guestVlan_get
* Description:
* Get 802.1x guest VLAN configuration
* Input:
* None
* Output:
* pVid - 802.1x guest VLAN ID
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The API can get 802.1x guest VLAN information.
*/
extern rtk_api_ret_t rtk_dot1x_guestVlan_get(rtk_vlan_t *pVid);
/* Function Name:
* rtk_dot1x_guestVlan2Auth_set
* Description:
* Set 802.1x guest VLAN to auth host configuration
* Input:
* enable - The status of guest VLAN to auth host.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameter.
* Note:
* The operational direction of 802.1x guest VLAN to auth host control is as following:
* - ENABLED
* - DISABLED
*/
extern rtk_api_ret_t rtk_dot1x_guestVlan2Auth_set(rtk_enable_t enable);
/* Function Name:
* rtk_dot1x_guestVlan2Auth_get
* Description:
* Get 802.1x guest VLAN to auth host configuration
* Input:
* None
* Output:
* pEnable - The status of guest VLAN to auth host.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The API can get 802.1x guest VLAN to auth host information.
*/
extern rtk_api_ret_t rtk_dot1x_guestVlan2Auth_get(rtk_enable_t *pEnable);
#endif /* __RTK_API_DOT1X_H__ */

View file

@ -0,0 +1,82 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* Purpose : RTL8367/RTL8367C switch high-level API
*
* Feature : The file includes EEE module high-layer API defination
*
*/
#ifndef __RTK_API_EEE_H__
#define __RTK_API_EEE_H__
/* Function Name:
* rtk_eee_init
* Description:
* EEE function initialization.
* Input:
* None
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
* This API is used to initialize EEE status.
*/
extern rtk_api_ret_t rtk_eee_init(void);
/* Function Name:
* rtk_eee_portEnable_set
* Description:
* Set enable status of EEE function.
* Input:
* port - port id.
* enable - enable EEE status.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_ENABLE - Invalid enable input.
* Note:
* This API can set EEE function to the specific port.
* The configuration of the port is as following:
* - DISABLE
* - ENABLE
*/
extern rtk_api_ret_t rtk_eee_portEnable_set(rtk_port_t port, rtk_enable_t enable);
/* Function Name:
* rtk_eee_portEnable_get
* Description:
* Get port admin configuration of the specific port.
* Input:
* port - Port id.
* Output:
* pEnable - Back pressure status.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* Note:
* This API can set EEE function to the specific port.
* The configuration of the port is as following:
* - DISABLE
* - ENABLE
*/
extern rtk_api_ret_t rtk_eee_portEnable_get(rtk_port_t port, rtk_enable_t *pEnable);
#endif /* __RTK_API_EEE_H__ */

View file

@ -0,0 +1,168 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* Purpose : RTL8367/RTL8367C switch high-level API
*
* Feature : The file includes I2C module high-layer API defination
*
*/
#ifndef __RTK_API_I2C_H__
#define __RTK_API_I2C_H__
#include <rtk_types.h>
#define I2C_GPIO_MAX_GROUP (3)
typedef enum rtk_I2C_16bit_mode_e{
I2C_LSB_16BIT_MODE = 0,
I2C_70B_LSB_16BIT_MODE,
I2C_Mode_END
}rtk_I2C_16bit_mode_t;
typedef enum rtk_I2C_gpio_pin_e{
I2C_GPIO_PIN_8_9 = 0,
I2C_GPIO_PIN_15_16 ,
I2C_GPIO_PIN_35_36 ,
I2C_GPIO_PIN_END
}rtk_I2C_gpio_pin_t;
/* Function Name:
* rtk_i2c_data_read
* Description:
* read i2c slave device register.
* Input:
* deviceAddr - access Slave device address
* slaveRegAddr - access Slave register address
* Output:
* pRegData - read data
* Return:
* RT_ERR_OK - OK
* RT_ERR_NULL_POINTER - input parameter is null pointer
* Note:
* The API can access i2c slave and read i2c slave device register.
*/
extern rtk_api_ret_t rtk_i2c_data_read(rtk_uint8 deviceAddr, rtk_uint32 slaveRegAddr, rtk_uint32 *pRegData);
/* Function Name:
* rtk_i2c_data_write
* Description:
* write data to i2c slave device register
* Input:
* deviceAddr - access Slave device address
* slaveRegAddr - access Slave register address
* regData - data to set
* Output:
* None
* Return:
* RT_ERR_OK - OK
* Note:
* The API can access i2c slave and setting i2c slave device register.
*/
extern rtk_api_ret_t rtk_i2c_data_write(rtk_uint8 deviceAddr, rtk_uint32 slaveRegAddr, rtk_uint32 regData);
/* Function Name:
* rtk_i2c_init
* Description:
* I2C smart function initialization.
* Input:
* None
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* Note:
* This API is used to initialize EEE status.
* need used GPIO pins
* OpenDrain and clock
*/
extern rtk_api_ret_t rtk_i2c_init(void);
/* Function Name:
* rtk_i2c_mode_set
* Description:
* Set I2C data byte-order.
* Input:
* i2cmode - byte-order mode
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_INPUT - Invalid input parameter.
* Note:
* This API can set I2c traffic's byte-order .
*/
extern rtk_api_ret_t rtk_i2c_mode_set( rtk_I2C_16bit_mode_t i2cmode);
/* Function Name:
* rtk_i2c_mode_get
* Description:
* Get i2c traffic byte-order setting.
* Input:
* None
* Output:
* pI2cMode - i2c byte-order
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_NULL_POINTER - input parameter is null pointer
* Note:
* The API can get i2c traffic byte-order setting.
*/
extern rtk_api_ret_t rtk_i2c_mode_get( rtk_I2C_16bit_mode_t * pI2cMode);
/* Function Name:
* rtk_i2c_gpioPinGroup_set
* Description:
* Set i2c SDA & SCL used GPIO pins group.
* Input:
* pins_group - GPIO pins group
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_INPUT - Invalid input parameter.
* Note:
* The API can set i2c used gpio pins group.
* There are three group pins could be used
*/
extern rtk_api_ret_t rtk_i2c_gpioPinGroup_set( rtk_I2C_gpio_pin_t pins_group);
/* Function Name:
* rtk_i2c_gpioPinGroup_get
* Description:
* Get i2c SDA & SCL used GPIO pins group.
* Input:
* None
* Output:
* pPins_group - GPIO pins group
* Return:
* RT_ERR_OK - OK
* RT_ERR_NULL_POINTER - input parameter is null pointer
* Note:
* The API can get i2c used gpio pins group.
* There are three group pins could be used
*/
extern rtk_api_ret_t rtk_i2c_gpioPinGroup_get(rtk_I2C_gpio_pin_t * pPins_group);
#endif

View file

@ -0,0 +1,769 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* Purpose : RTL8367/RTL8367C switch high-level API
*
* Feature : The file includes IGMP module high-layer API defination
*
*/
#ifndef __RTK_API_IGMP_H__
#define __RTK_API_IGMP_H__
/*
* Data Type Declaration
*/
typedef enum rtk_igmp_type_e
{
IGMP_IPV4 = 0,
IGMP_PPPOE_IPV4,
IGMP_MLD,
IGMP_PPPOE_MLD,
IGMP_TYPE_END
} rtk_igmp_type_t;
typedef enum rtk_trap_igmp_action_e
{
IGMP_ACTION_FORWARD = 0,
IGMP_ACTION_TRAP2CPU,
IGMP_ACTION_DROP,
IGMP_ACTION_ASIC,
IGMP_ACTION_END
} rtk_igmp_action_t;
typedef enum rtk_igmp_protocol_e
{
PROTOCOL_IGMPv1 = 0,
PROTOCOL_IGMPv2,
PROTOCOL_IGMPv3,
PROTOCOL_MLDv1,
PROTOCOL_MLDv2,
PROTOCOL_END
} rtk_igmp_protocol_t;
typedef enum rtk_igmp_tableFullAction_e
{
IGMP_TABLE_FULL_FORWARD = 0,
IGMP_TABLE_FULL_DROP,
IGMP_TABLE_FULL_TRAP,
IGMP_TABLE_FULL_OP_END
}rtk_igmp_tableFullAction_t;
typedef enum rtk_igmp_checksumErrorAction_e
{
IGMP_CRC_ERR_DROP = 0,
IGMP_CRC_ERR_TRAP,
IGMP_CRC_ERR_FORWARD,
IGMP_CRC_ERR_OP_END
}rtk_igmp_checksumErrorAction_t;
typedef enum rtk_igmp_bypassGroup_e
{
IGMP_BYPASS_224_0_0_X = 0,
IGMP_BYPASS_224_0_1_X,
IGMP_BYPASS_239_255_255_X,
IGMP_BYPASS_IPV6_00XX,
IGMP_BYPASS_GROUP_END
}rtk_igmp_bypassGroup_t;
typedef struct rtk_igmp_dynamicRouterPort_s
{
rtk_enable_t dynamicRouterPort0Valid;
rtk_port_t dynamicRouterPort0;
rtk_uint32 dynamicRouterPort0Timer;
rtk_enable_t dynamicRouterPort1Valid;
rtk_port_t dynamicRouterPort1;
rtk_uint32 dynamicRouterPort1Timer;
}rtk_igmp_dynamicRouterPort_t;
typedef struct rtk_igmp_rxPktEnable_s
{
rtk_enable_t rxQuery;
rtk_enable_t rxReport;
rtk_enable_t rxLeave;
rtk_enable_t rxMRP;
rtk_enable_t rxMcast;
}rtk_igmp_rxPktEnable_t;
typedef struct rtk_igmp_groupInfo_s
{
rtk_enable_t valid;
rtk_portmask_t member;
rtk_uint32 timer[RTK_PORT_MAX];
rtk_uint32 reportSuppFlag;
}rtk_igmp_groupInfo_t;
typedef enum rtk_igmp_ReportLeaveFwdAct_e
{
IGMP_REPORT_LEAVE_TO_ROUTER = 0,
IGMP_REPORT_LEAVE_TO_ALLPORT,
IGMP_REPORT_LEAVE_TO_ROUTER_PORT_ADV,
IGMP_REPORT_LEAVE_ACT_END
}rtk_igmp_ReportLeaveFwdAct_t;
/* Function Name:
* rtk_igmp_init
* Description:
* This API enables H/W IGMP and set a default initial configuration.
* Input:
* None.
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
* This API enables H/W IGMP and set a default initial configuration.
*/
extern rtk_api_ret_t rtk_igmp_init(void);
/* Function Name:
* rtk_igmp_state_set
* Description:
* This API set H/W IGMP state.
* Input:
* enabled - H/W IGMP state
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Error parameter
* Note:
* This API set H/W IGMP state.
*/
extern rtk_api_ret_t rtk_igmp_state_set(rtk_enable_t enabled);
/* Function Name:
* rtk_igmp_state_get
* Description:
* This API get H/W IGMP state.
* Input:
* None.
* Output:
* pEnabled - H/W IGMP state
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Error parameter
* Note:
* This API set current H/W IGMP state.
*/
extern rtk_api_ret_t rtk_igmp_state_get(rtk_enable_t *pEnabled);
/* Function Name:
* rtk_igmp_static_router_port_set
* Description:
* Configure static router port
* Input:
* pPortmask - Static Port mask
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_MASK - Error parameter
* Note:
* This API set static router port
*/
extern rtk_api_ret_t rtk_igmp_static_router_port_set(rtk_portmask_t *pPortmask);
/* Function Name:
* rtk_igmp_static_router_port_get
* Description:
* Get static router port
* Input:
* None.
* Output:
* pPortmask - Static port mask
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_MASK - Error parameter
* Note:
* This API get static router port
*/
extern rtk_api_ret_t rtk_igmp_static_router_port_get(rtk_portmask_t *pPortmask);
/* Function Name:
* rtk_igmp_protocol_set
* Description:
* set IGMP/MLD protocol action
* Input:
* port - Port ID
* protocol - IGMP/MLD protocol
* action - Per-port and per-protocol IGMP action seeting
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_MASK - Error parameter
* Note:
* This API set IGMP/MLD protocol action
*/
extern rtk_api_ret_t rtk_igmp_protocol_set(rtk_port_t port, rtk_igmp_protocol_t protocol, rtk_igmp_action_t action);
/* Function Name:
* rtk_igmp_protocol_get
* Description:
* set IGMP/MLD protocol action
* Input:
* port - Port ID
* protocol - IGMP/MLD protocol
* action - Per-port and per-protocol IGMP action seeting
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_MASK - Error parameter
* Note:
* This API set IGMP/MLD protocol action
*/
extern rtk_api_ret_t rtk_igmp_protocol_get(rtk_port_t port, rtk_igmp_protocol_t protocol, rtk_igmp_action_t *pAction);
/* Function Name:
* rtk_igmp_fastLeave_set
* Description:
* set IGMP/MLD FastLeave state
* Input:
* state - ENABLED: Enable FastLeave, DISABLED: disable FastLeave
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_INPUT - Error Input
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
* This API set IGMP/MLD FastLeave state
*/
extern rtk_api_ret_t rtk_igmp_fastLeave_set(rtk_enable_t state);
/* Function Name:
* rtk_igmp_fastLeave_get
* Description:
* get IGMP/MLD FastLeave state
* Input:
* None
* Output:
* pState - ENABLED: Enable FastLeave, DISABLED: disable FastLeave
* Return:
* RT_ERR_OK - OK
* RT_ERR_NULL_POINTER - NULL pointer
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
* This API get IGMP/MLD FastLeave state
*/
extern rtk_api_ret_t rtk_igmp_fastLeave_get(rtk_enable_t *pState);
/* Function Name:
* rtk_igmp_maxGroup_set
* Description:
* Set per port multicast group learning limit.
* Input:
* port - Port ID
* group - The number of multicast group learning limit.
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_PORT_ID - Error Port ID
* RT_ERR_OUT_OF_RANGE - parameter out of range
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
* This API set per port multicast group learning limit.
*/
extern rtk_api_ret_t rtk_igmp_maxGroup_set(rtk_port_t port, rtk_uint32 group);
/* Function Name:
* rtk_igmp_maxGroup_get
* Description:
* Get per port multicast group learning limit.
* Input:
* port - Port ID
* Output:
* pGroup - The number of multicast group learning limit.
* Return:
* RT_ERR_OK - OK
* RT_ERR_PORT_ID - Error Port ID
* RT_ERR_NULL_POINTER - Null pointer
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
* This API get per port multicast group learning limit.
*/
extern rtk_api_ret_t rtk_igmp_maxGroup_get(rtk_port_t port, rtk_uint32 *pGroup);
/* Function Name:
* rtk_igmp_currentGroup_get
* Description:
* Get per port multicast group learning count.
* Input:
* port - Port ID
* Output:
* pGroup - The number of multicast group learning count.
* Return:
* RT_ERR_OK - OK
* RT_ERR_PORT_ID - Error Port ID
* RT_ERR_NULL_POINTER - Null pointer
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
* This API get per port multicast group learning count.
*/
extern rtk_api_ret_t rtk_igmp_currentGroup_get(rtk_port_t port, rtk_uint32 *pGroup);
/* Function Name:
* rtk_igmp_tableFullAction_set
* Description:
* set IGMP/MLD Table Full Action
* Input:
* action - Table Full Action
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_INPUT - Error Input
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
*/
extern rtk_api_ret_t rtk_igmp_tableFullAction_set(rtk_igmp_tableFullAction_t action);
/* Function Name:
* rtk_igmp_tableFullAction_get
* Description:
* get IGMP/MLD Table Full Action
* Input:
* None
* Output:
* pAction - Table Full Action
* Return:
* RT_ERR_OK - OK
* RT_ERR_NULL_POINTER - Null pointer
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
*/
extern rtk_api_ret_t rtk_igmp_tableFullAction_get(rtk_igmp_tableFullAction_t *pAction);
/* Function Name:
* rtk_igmp_checksumErrorAction_set
* Description:
* set IGMP/MLD Checksum Error Action
* Input:
* action - Checksum error Action
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_INPUT - Error Input
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
*/
extern rtk_api_ret_t rtk_igmp_checksumErrorAction_set(rtk_igmp_checksumErrorAction_t action);
/* Function Name:
* rtk_igmp_checksumErrorAction_get
* Description:
* get IGMP/MLD Checksum Error Action
* Input:
* None
* Output:
* pAction - Checksum error Action
* Return:
* RT_ERR_OK - OK
* RT_ERR_NULL_POINTER - Null pointer
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
*/
extern rtk_api_ret_t rtk_igmp_checksumErrorAction_get(rtk_igmp_checksumErrorAction_t *pAction);
/* Function Name:
* rtk_igmp_leaveTimer_set
* Description:
* set IGMP/MLD Leave timer
* Input:
* timer - Leave timer
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_INPUT - Error Input
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
*/
extern rtk_api_ret_t rtk_igmp_leaveTimer_set(rtk_uint32 timer);
/* Function Name:
* rtk_igmp_leaveTimer_get
* Description:
* get IGMP/MLD Leave timer
* Input:
* None
* Output:
* pTimer - Leave Timer.
* Return:
* RT_ERR_OK - OK
* RT_ERR_NULL_POINTER - Null pointer
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
*/
extern rtk_api_ret_t rtk_igmp_leaveTimer_get(rtk_uint32 *pTimer);
/* Function Name:
* rtk_igmp_queryInterval_set
* Description:
* set IGMP/MLD Query Interval
* Input:
* interval - Query Interval
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_INPUT - Error Input
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
*/
extern rtk_api_ret_t rtk_igmp_queryInterval_set(rtk_uint32 interval);
/* Function Name:
* rtk_igmp_queryInterval_get
* Description:
* get IGMP/MLD Query Interval
* Input:
* None.
* Output:
* pInterval - Query Interval
* Return:
* RT_ERR_OK - OK
* RT_ERR_NULL_POINTER - Null pointer
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
*/
extern rtk_api_ret_t rtk_igmp_queryInterval_get(rtk_uint32 *pInterval);
/* Function Name:
* rtk_igmp_robustness_set
* Description:
* set IGMP/MLD Robustness value
* Input:
* robustness - Robustness value
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_INPUT - Error Input
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
*/
extern rtk_api_ret_t rtk_igmp_robustness_set(rtk_uint32 robustness);
/* Function Name:
* rtk_igmp_robustness_get
* Description:
* get IGMP/MLD Robustness value
* Input:
* None
* Output:
* pRobustness - Robustness value.
* Return:
* RT_ERR_OK - OK
* RT_ERR_NULL_POINTER - Null pointer
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
*/
extern rtk_api_ret_t rtk_igmp_robustness_get(rtk_uint32 *pRobustness);
/* Function Name:
* rtk_igmp_dynamicRouterRortAllow_set
* Description:
* Configure dynamic router port allow option
* Input:
* pPortmask - Dynamic Port allow mask
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_MASK - Error parameter
* Note:
*
*/
extern rtk_api_ret_t rtk_igmp_dynamicRouterPortAllow_set(rtk_portmask_t *pPortmask);
/* Function Name:
* rtk_igmp_dynamicRouterRortAllow_get
* Description:
* Get dynamic router port allow option
* Input:
* None.
* Output:
* pPortmask - Dynamic Port allow mask
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_MASK - Error parameter
* Note:
*
*/
extern rtk_api_ret_t rtk_igmp_dynamicRouterPortAllow_get(rtk_portmask_t *pPortmask);
/* Function Name:
* rtk_igmp_dynamicRouterPort_get
* Description:
* Get dynamic router port
* Input:
* None.
* Output:
* pDynamicRouterPort - Dynamic Router Port
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_NULL_POINTER - Null pointer
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_MASK - Error parameter
* Note:
*
*/
extern rtk_api_ret_t rtk_igmp_dynamicRouterPort_get(rtk_igmp_dynamicRouterPort_t *pDynamicRouterPort);
/* Function Name:
* rtk_igmp_suppressionEnable_set
* Description:
* Configure IGMPv1/v2 & MLDv1 Report/Leave/Done suppression
* Input:
* reportSuppression - Report suppression
* leaveSuppression - Leave suppression
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Error Input
* Note:
*
*/
extern rtk_api_ret_t rtk_igmp_suppressionEnable_set(rtk_enable_t reportSuppression, rtk_enable_t leaveSuppression);
/* Function Name:
* rtk_igmp_suppressionEnable_get
* Description:
* Get IGMPv1/v2 & MLDv1 Report/Leave/Done suppression
* Input:
* None
* Output:
* pReportSuppression - Report suppression
* pLeaveSuppression - Leave suppression
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_NULL_POINTER - Null pointer
* Note:
*
*/
extern rtk_api_ret_t rtk_igmp_suppressionEnable_get(rtk_enable_t *pReportSuppression, rtk_enable_t *pLeaveSuppression);
/* Function Name:
* rtk_igmp_portRxPktEnable_set
* Description:
* Configure IGMP/MLD RX Packet configuration
* Input:
* port - Port ID
* pRxCfg - RX Packet Configuration
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Error Input
* RT_ERR_NULL_POINTER - Null pointer
* Note:
*
*/
extern rtk_api_ret_t rtk_igmp_portRxPktEnable_set(rtk_port_t port, rtk_igmp_rxPktEnable_t *pRxCfg);
/* Function Name:
* rtk_igmp_portRxPktEnable_get
* Description:
* Get IGMP/MLD RX Packet configuration
* Input:
* port - Port ID
* pRxCfg - RX Packet Configuration
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Error Input
* RT_ERR_NULL_POINTER - Null pointer
* Note:
*
*/
extern rtk_api_ret_t rtk_igmp_portRxPktEnable_get(rtk_port_t port, rtk_igmp_rxPktEnable_t *pRxCfg);
/* Function Name:
* rtk_igmp_groupInfo_get
* Description:
* Get IGMP/MLD Group database
* Input:
* indes - Index (0~255)
* Output:
* pGroup - Group database information.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Error Input
* RT_ERR_NULL_POINTER - Null pointer
* Note:
*
*/
extern rtk_api_ret_t rtk_igmp_groupInfo_get(rtk_uint32 index, rtk_igmp_groupInfo_t *pGroup);
/* Function Name:
* rtk_igmp_ReportLeaveFwdAction_set
* Description:
* Set Report Leave packet forwarding action
* Input:
* action - Action
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Error Input
* Note:
*
*/
extern rtk_api_ret_t rtk_igmp_ReportLeaveFwdAction_set(rtk_igmp_ReportLeaveFwdAct_t action);
/* Function Name:
* rtk_igmp_ReportLeaveFwdAction_get
* Description:
* Get Report Leave packet forwarding action
* Input:
* action - Action
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Error Input
* RT_ERR_NULL_POINTER - Null Pointer
* Note:
*
*/
extern rtk_api_ret_t rtk_igmp_ReportLeaveFwdAction_get(rtk_igmp_ReportLeaveFwdAct_t *pAction);
/* Function Name:
* rtk_igmp_dropLeaveZeroEnable_set
* Description:
* Set the function of droppping Leave packet with group IP = 0.0.0.0
* Input:
* enabled - Action 1: drop, 0:pass
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Error Input
* Note:
*
*/
extern rtk_api_ret_t rtk_igmp_dropLeaveZeroEnable_set(rtk_enable_t enabled);
/* Function Name:
* rtk_igmp_dropLeaveZeroEnable_get
* Description:
* Get the function of droppping Leave packet with group IP = 0.0.0.0
* Input:
* None
* Output:
* pEnabled. - Action 1: drop, 0:pass
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Error Input
* RT_ERR_NULL_POINTER - Null Pointer
* Note:
*
*/
extern rtk_api_ret_t rtk_igmp_dropLeaveZeroEnable_get(rtk_enable_t *pEnabled);
/* Function Name:
* rtk_igmp_bypassGroupRange_set
* Description:
* Set Bypass group
* Input:
* group - bypassed group
* enabled - enabled 1: Bypassed, 0: not bypass
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Error Input
* Note:
*
*/
extern rtk_api_ret_t rtk_igmp_bypassGroupRange_set(rtk_igmp_bypassGroup_t group, rtk_enable_t enabled);
/* Function Name:
* rtk_igmp_bypassGroupRange_get
* Description:
* get Bypass group
* Input:
* group - bypassed group
* Output:
* pEnable - enabled 1: Bypassed, 0: not bypass
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Error Input
* RT_ERR_NULL_POINTER - Null Pointer
* Note:
*
*/
extern rtk_api_ret_t rtk_igmp_bypassGroupRange_get(rtk_igmp_bypassGroup_t group, rtk_enable_t *pEnable);
#endif /* __RTK_API_IGMP_H__ */

View file

@ -0,0 +1,254 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* Purpose : RTL8367/RTL8367C switch high-level API
*
* Feature : The file includes Interrupt module high-layer API defination
*
*/
#ifndef __RTK_API_INTERRUPT_H__
#define __RTK_API_INTERRUPT_H__
/*
* Data Type Declaration
*/
#define RTK_MAX_NUM_OF_INTERRUPT_TYPE 1
typedef struct rtk_int_status_s
{
rtk_uint16 value[RTK_MAX_NUM_OF_INTERRUPT_TYPE];
} rtk_int_status_t;
typedef struct rtk_int_info_s
{
rtk_portmask_t portMask;
rtk_uint32 meterMask;
rtk_uint32 systemLearnOver;
}rtk_int_info_t;
typedef enum rtk_int_type_e
{
INT_TYPE_LINK_STATUS = 0,
INT_TYPE_METER_EXCEED,
INT_TYPE_LEARN_LIMIT,
INT_TYPE_LINK_SPEED,
INT_TYPE_CONGEST,
INT_TYPE_GREEN_FEATURE,
INT_TYPE_LOOP_DETECT,
INT_TYPE_8051,
INT_TYPE_CABLE_DIAG,
INT_TYPE_ACL,
INT_TYPE_RESERVED, /* Unused */
INT_TYPE_SLIENT,
INT_TYPE_END
}rtk_int_type_t;
typedef enum rtk_int_advType_e
{
ADV_L2_LEARN_PORT_MASK = 0,
ADV_SPEED_CHANGE_PORT_MASK,
ADV_SPECIAL_CONGESTION_PORT_MASK,
ADV_PORT_LINKDOWN_PORT_MASK,
ADV_PORT_LINKUP_PORT_MASK,
ADV_METER_EXCEED_MASK,
ADV_RLDP_LOOPED,
ADV_RLDP_RELEASED,
ADV_END,
} rtk_int_advType_t;
typedef enum rtk_int_polarity_e
{
INT_POLAR_HIGH = 0,
INT_POLAR_LOW,
INT_POLAR_END
} rtk_int_polarity_t;
/* Function Name:
* rtk_int_polarity_set
* Description:
* Set interrupt polarity configuration.
* Input:
* type - Interruptpolarity type.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The API can set interrupt polarity configuration.
*/
extern rtk_api_ret_t rtk_int_polarity_set(rtk_int_polarity_t type);
/* Function Name:
* rtk_int_polarity_get
* Description:
* Get interrupt polarity configuration.
* Input:
* None
* Output:
* pType - Interruptpolarity type.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
* The API can get interrupt polarity configuration.
*/
extern rtk_api_ret_t rtk_int_polarity_get(rtk_int_polarity_t *pType);
/* Function Name:
* rtk_int_control_set
* Description:
* Set interrupt trigger status configuration.
* Input:
* type - Interrupt type.
* enable - Interrupt status.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_ENABLE - Invalid enable input.
* Note:
* The API can set interrupt status configuration.
* The interrupt trigger status is shown in the following:
* - INT_TYPE_LINK_STATUS
* - INT_TYPE_METER_EXCEED
* - INT_TYPE_LEARN_LIMIT
* - INT_TYPE_LINK_SPEED
* - INT_TYPE_CONGEST
* - INT_TYPE_GREEN_FEATURE
* - INT_TYPE_LOOP_DETECT
* - INT_TYPE_8051,
* - INT_TYPE_CABLE_DIAG,
* - INT_TYPE_ACL,
* - INT_TYPE_SLIENT
*/
extern rtk_api_ret_t rtk_int_control_set(rtk_int_type_t type, rtk_enable_t enable);
/* Function Name:
* rtk_int_control_get
* Description:
* Get interrupt trigger status configuration.
* Input:
* type - Interrupt type.
* Output:
* pEnable - Interrupt status.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The API can get interrupt status configuration.
* The interrupt trigger status is shown in the following:
* - INT_TYPE_LINK_STATUS
* - INT_TYPE_METER_EXCEED
* - INT_TYPE_LEARN_LIMIT
* - INT_TYPE_LINK_SPEED
* - INT_TYPE_CONGEST
* - INT_TYPE_GREEN_FEATURE
* - INT_TYPE_LOOP_DETECT
* - INT_TYPE_8051,
* - INT_TYPE_CABLE_DIAG,
* - INT_TYPE_ACL,
* - INT_TYPE_SLIENT
*/
extern rtk_api_ret_t rtk_int_control_get(rtk_int_type_t type, rtk_enable_t* pEnable);
/* Function Name:
* rtk_int_status_set
* Description:
* Set interrupt trigger status to clean.
* Input:
* None
* Output:
* pStatusMask - Interrupt status bit mask.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The API can clean interrupt trigger status when interrupt happened.
* The interrupt trigger status is shown in the following:
* - INT_TYPE_LINK_STATUS (value[0] (Bit0))
* - INT_TYPE_METER_EXCEED (value[0] (Bit1))
* - INT_TYPE_LEARN_LIMIT (value[0] (Bit2))
* - INT_TYPE_LINK_SPEED (value[0] (Bit3))
* - INT_TYPE_CONGEST (value[0] (Bit4))
* - INT_TYPE_GREEN_FEATURE (value[0] (Bit5))
* - INT_TYPE_LOOP_DETECT (value[0] (Bit6))
* - INT_TYPE_8051 (value[0] (Bit7))
* - INT_TYPE_CABLE_DIAG (value[0] (Bit8))
* - INT_TYPE_ACL (value[0] (Bit9))
* - INT_TYPE_SLIENT (value[0] (Bit11))
* The status will be cleared after execute this API.
*/
extern rtk_api_ret_t rtk_int_status_set(rtk_int_status_t *pStatusMask);
/* Function Name:
* rtk_int_status_get
* Description:
* Get interrupt trigger status.
* Input:
* None
* Output:
* pStatusMask - Interrupt status bit mask.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The API can get interrupt trigger status when interrupt happened.
* The interrupt trigger status is shown in the following:
* - INT_TYPE_LINK_STATUS (value[0] (Bit0))
* - INT_TYPE_METER_EXCEED (value[0] (Bit1))
* - INT_TYPE_LEARN_LIMIT (value[0] (Bit2))
* - INT_TYPE_LINK_SPEED (value[0] (Bit3))
* - INT_TYPE_CONGEST (value[0] (Bit4))
* - INT_TYPE_GREEN_FEATURE (value[0] (Bit5))
* - INT_TYPE_LOOP_DETECT (value[0] (Bit6))
* - INT_TYPE_8051 (value[0] (Bit7))
* - INT_TYPE_CABLE_DIAG (value[0] (Bit8))
* - INT_TYPE_ACL (value[0] (Bit9))
* - INT_TYPE_SLIENT (value[0] (Bit11))
*
*/
extern rtk_api_ret_t rtk_int_status_get(rtk_int_status_t* pStatusMask);
/* Function Name:
* rtk_int_advanceInfo_get
* Description:
* Get interrupt advanced information.
* Input:
* adv_type - Advanced interrupt type.
* Output:
* info - Information per type.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* This API can get advanced information when interrupt happened.
* The status will be cleared after execute this API.
*/
extern rtk_api_ret_t rtk_int_advanceInfo_get(rtk_int_advType_t adv_type, rtk_int_info_t* info);
#endif /* __RTK_API_INTERRUPT_H__ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,371 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* Purpose : RTL8367/RTL8367C switch high-level API
*
* Feature : The file includes Leaky module high-layer API defination
*
*/
#ifndef __RTK_API_LEAKY_H__
#define __RTK_API_LEAKY_H__
typedef enum rtk_leaky_type_e
{
LEAKY_BRG_GROUP = 0,
LEAKY_FD_PAUSE,
LEAKY_SP_MCAST,
LEAKY_1X_PAE,
LEAKY_UNDEF_BRG_04,
LEAKY_UNDEF_BRG_05,
LEAKY_UNDEF_BRG_06,
LEAKY_UNDEF_BRG_07,
LEAKY_PROVIDER_BRIDGE_GROUP_ADDRESS,
LEAKY_UNDEF_BRG_09,
LEAKY_UNDEF_BRG_0A,
LEAKY_UNDEF_BRG_0B,
LEAKY_UNDEF_BRG_0C,
LEAKY_PROVIDER_BRIDGE_GVRP_ADDRESS,
LEAKY_8021AB,
LEAKY_UNDEF_BRG_0F,
LEAKY_BRG_MNGEMENT,
LEAKY_UNDEFINED_11,
LEAKY_UNDEFINED_12,
LEAKY_UNDEFINED_13,
LEAKY_UNDEFINED_14,
LEAKY_UNDEFINED_15,
LEAKY_UNDEFINED_16,
LEAKY_UNDEFINED_17,
LEAKY_UNDEFINED_18,
LEAKY_UNDEFINED_19,
LEAKY_UNDEFINED_1A,
LEAKY_UNDEFINED_1B,
LEAKY_UNDEFINED_1C,
LEAKY_UNDEFINED_1D,
LEAKY_UNDEFINED_1E,
LEAKY_UNDEFINED_1F,
LEAKY_GMRP,
LEAKY_GVRP,
LEAKY_UNDEF_GARP_22,
LEAKY_UNDEF_GARP_23,
LEAKY_UNDEF_GARP_24,
LEAKY_UNDEF_GARP_25,
LEAKY_UNDEF_GARP_26,
LEAKY_UNDEF_GARP_27,
LEAKY_UNDEF_GARP_28,
LEAKY_UNDEF_GARP_29,
LEAKY_UNDEF_GARP_2A,
LEAKY_UNDEF_GARP_2B,
LEAKY_UNDEF_GARP_2C,
LEAKY_UNDEF_GARP_2D,
LEAKY_UNDEF_GARP_2E,
LEAKY_UNDEF_GARP_2F,
LEAKY_IGMP,
LEAKY_IPMULTICAST,
LEAKY_CDP,
LEAKY_CSSTP,
LEAKY_LLDP,
LEAKY_END,
}rtk_leaky_type_t;
/* Function Name:
* rtk_leaky_vlan_set
* Description:
* Set VLAN leaky.
* Input:
* type - Packet type for VLAN leaky.
* enable - Leaky status.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_ENABLE - Invalid enable input
* Note:
* This API can set VLAN leaky for RMA ,IGMP/MLD, CDP, CSSTP, and LLDP packets.
* The leaky frame types are as following:
* - LEAKY_BRG_GROUP,
* - LEAKY_FD_PAUSE,
* - LEAKY_SP_MCAST,
* - LEAKY_1X_PAE,
* - LEAKY_UNDEF_BRG_04,
* - LEAKY_UNDEF_BRG_05,
* - LEAKY_UNDEF_BRG_06,
* - LEAKY_UNDEF_BRG_07,
* - LEAKY_PROVIDER_BRIDGE_GROUP_ADDRESS,
* - LEAKY_UNDEF_BRG_09,
* - LEAKY_UNDEF_BRG_0A,
* - LEAKY_UNDEF_BRG_0B,
* - LEAKY_UNDEF_BRG_0C,
* - LEAKY_PROVIDER_BRIDGE_GVRP_ADDRESS,
* - LEAKY_8021AB,
* - LEAKY_UNDEF_BRG_0F,
* - LEAKY_BRG_MNGEMENT,
* - LEAKY_UNDEFINED_11,
* - LEAKY_UNDEFINED_12,
* - LEAKY_UNDEFINED_13,
* - LEAKY_UNDEFINED_14,
* - LEAKY_UNDEFINED_15,
* - LEAKY_UNDEFINED_16,
* - LEAKY_UNDEFINED_17,
* - LEAKY_UNDEFINED_18,
* - LEAKY_UNDEFINED_19,
* - LEAKY_UNDEFINED_1A,
* - LEAKY_UNDEFINED_1B,
* - LEAKY_UNDEFINED_1C,
* - LEAKY_UNDEFINED_1D,
* - LEAKY_UNDEFINED_1E,
* - LEAKY_UNDEFINED_1F,
* - LEAKY_GMRP,
* - LEAKY_GVRP,
* - LEAKY_UNDEF_GARP_22,
* - LEAKY_UNDEF_GARP_23,
* - LEAKY_UNDEF_GARP_24,
* - LEAKY_UNDEF_GARP_25,
* - LEAKY_UNDEF_GARP_26,
* - LEAKY_UNDEF_GARP_27,
* - LEAKY_UNDEF_GARP_28,
* - LEAKY_UNDEF_GARP_29,
* - LEAKY_UNDEF_GARP_2A,
* - LEAKY_UNDEF_GARP_2B,
* - LEAKY_UNDEF_GARP_2C,
* - LEAKY_UNDEF_GARP_2D,
* - LEAKY_UNDEF_GARP_2E,
* - LEAKY_UNDEF_GARP_2F,
* - LEAKY_IGMP,
* - LEAKY_IPMULTICAST.
* - LEAKY_CDP,
* - LEAKY_CSSTP,
* - LEAKY_LLDP.
*/
extern rtk_api_ret_t rtk_leaky_vlan_set(rtk_leaky_type_t type, rtk_enable_t enable);
/* Function Name:
* rtk_leaky_vlan_get
* Description:
* Get VLAN leaky.
* Input:
* type - Packet type for VLAN leaky.
* Output:
* pEnable - Leaky status.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* This API can get VLAN leaky status for RMA ,IGMP/MLD, CDP, CSSTP, and LLDP packets.
* The leaky frame types are as following:
* - LEAKY_BRG_GROUP,
* - LEAKY_FD_PAUSE,
* - LEAKY_SP_MCAST,
* - LEAKY_1X_PAE,
* - LEAKY_UNDEF_BRG_04,
* - LEAKY_UNDEF_BRG_05,
* - LEAKY_UNDEF_BRG_06,
* - LEAKY_UNDEF_BRG_07,
* - LEAKY_PROVIDER_BRIDGE_GROUP_ADDRESS,
* - LEAKY_UNDEF_BRG_09,
* - LEAKY_UNDEF_BRG_0A,
* - LEAKY_UNDEF_BRG_0B,
* - LEAKY_UNDEF_BRG_0C,
* - LEAKY_PROVIDER_BRIDGE_GVRP_ADDRESS,
* - LEAKY_8021AB,
* - LEAKY_UNDEF_BRG_0F,
* - LEAKY_BRG_MNGEMENT,
* - LEAKY_UNDEFINED_11,
* - LEAKY_UNDEFINED_12,
* - LEAKY_UNDEFINED_13,
* - LEAKY_UNDEFINED_14,
* - LEAKY_UNDEFINED_15,
* - LEAKY_UNDEFINED_16,
* - LEAKY_UNDEFINED_17,
* - LEAKY_UNDEFINED_18,
* - LEAKY_UNDEFINED_19,
* - LEAKY_UNDEFINED_1A,
* - LEAKY_UNDEFINED_1B,
* - LEAKY_UNDEFINED_1C,
* - LEAKY_UNDEFINED_1D,
* - LEAKY_UNDEFINED_1E,
* - LEAKY_UNDEFINED_1F,
* - LEAKY_GMRP,
* - LEAKY_GVRP,
* - LEAKY_UNDEF_GARP_22,
* - LEAKY_UNDEF_GARP_23,
* - LEAKY_UNDEF_GARP_24,
* - LEAKY_UNDEF_GARP_25,
* - LEAKY_UNDEF_GARP_26,
* - LEAKY_UNDEF_GARP_27,
* - LEAKY_UNDEF_GARP_28,
* - LEAKY_UNDEF_GARP_29,
* - LEAKY_UNDEF_GARP_2A,
* - LEAKY_UNDEF_GARP_2B,
* - LEAKY_UNDEF_GARP_2C,
* - LEAKY_UNDEF_GARP_2D,
* - LEAKY_UNDEF_GARP_2E,
* - LEAKY_UNDEF_GARP_2F,
* - LEAKY_IGMP,
* - LEAKY_IPMULTICAST.
* - LEAKY_CDP,
* - LEAKY_CSSTP,
* - LEAKY_LLDP.
*/
extern rtk_api_ret_t rtk_leaky_vlan_get(rtk_leaky_type_t type, rtk_enable_t *pEnable);
/* Function Name:
* rtk_leaky_portIsolation_set
* Description:
* Set port isolation leaky.
* Input:
* type - Packet type for port isolation leaky.
* enable - Leaky status.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_ENABLE - Invalid enable input
* Note:
* This API can set port isolation leaky for RMA ,IGMP/MLD, CDP, CSSTP, and LLDP packets.
* The leaky frame types are as following:
* - LEAKY_BRG_GROUP,
* - LEAKY_FD_PAUSE,
* - LEAKY_SP_MCAST,
* - LEAKY_1X_PAE,
* - LEAKY_UNDEF_BRG_04,
* - LEAKY_UNDEF_BRG_05,
* - LEAKY_UNDEF_BRG_06,
* - LEAKY_UNDEF_BRG_07,
* - LEAKY_PROVIDER_BRIDGE_GROUP_ADDRESS,
* - LEAKY_UNDEF_BRG_09,
* - LEAKY_UNDEF_BRG_0A,
* - LEAKY_UNDEF_BRG_0B,
* - LEAKY_UNDEF_BRG_0C,
* - LEAKY_PROVIDER_BRIDGE_GVRP_ADDRESS,
* - LEAKY_8021AB,
* - LEAKY_UNDEF_BRG_0F,
* - LEAKY_BRG_MNGEMENT,
* - LEAKY_UNDEFINED_11,
* - LEAKY_UNDEFINED_12,
* - LEAKY_UNDEFINED_13,
* - LEAKY_UNDEFINED_14,
* - LEAKY_UNDEFINED_15,
* - LEAKY_UNDEFINED_16,
* - LEAKY_UNDEFINED_17,
* - LEAKY_UNDEFINED_18,
* - LEAKY_UNDEFINED_19,
* - LEAKY_UNDEFINED_1A,
* - LEAKY_UNDEFINED_1B,
* - LEAKY_UNDEFINED_1C,
* - LEAKY_UNDEFINED_1D,
* - LEAKY_UNDEFINED_1E,
* - LEAKY_UNDEFINED_1F,
* - LEAKY_GMRP,
* - LEAKY_GVRP,
* - LEAKY_UNDEF_GARP_22,
* - LEAKY_UNDEF_GARP_23,
* - LEAKY_UNDEF_GARP_24,
* - LEAKY_UNDEF_GARP_25,
* - LEAKY_UNDEF_GARP_26,
* - LEAKY_UNDEF_GARP_27,
* - LEAKY_UNDEF_GARP_28,
* - LEAKY_UNDEF_GARP_29,
* - LEAKY_UNDEF_GARP_2A,
* - LEAKY_UNDEF_GARP_2B,
* - LEAKY_UNDEF_GARP_2C,
* - LEAKY_UNDEF_GARP_2D,
* - LEAKY_UNDEF_GARP_2E,
* - LEAKY_UNDEF_GARP_2F,
* - LEAKY_IGMP,
* - LEAKY_IPMULTICAST.
* - LEAKY_CDP,
* - LEAKY_CSSTP,
* - LEAKY_LLDP.
*/
extern rtk_api_ret_t rtk_leaky_portIsolation_set(rtk_leaky_type_t type, rtk_enable_t enable);
/* Function Name:
* rtk_leaky_portIsolation_get
* Description:
* Get port isolation leaky.
* Input:
* type - Packet type for port isolation leaky.
* Output:
* pEnable - Leaky status.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* This API can get port isolation leaky status for RMA ,IGMP/MLD, CDP, CSSTP, and LLDP packets.
* The leaky frame types are as following:
* - LEAKY_BRG_GROUP,
* - LEAKY_FD_PAUSE,
* - LEAKY_SP_MCAST,
* - LEAKY_1X_PAE,
* - LEAKY_UNDEF_BRG_04,
* - LEAKY_UNDEF_BRG_05,
* - LEAKY_UNDEF_BRG_06,
* - LEAKY_UNDEF_BRG_07,
* - LEAKY_PROVIDER_BRIDGE_GROUP_ADDRESS,
* - LEAKY_UNDEF_BRG_09,
* - LEAKY_UNDEF_BRG_0A,
* - LEAKY_UNDEF_BRG_0B,
* - LEAKY_UNDEF_BRG_0C,
* - LEAKY_PROVIDER_BRIDGE_GVRP_ADDRESS,
* - LEAKY_8021AB,
* - LEAKY_UNDEF_BRG_0F,
* - LEAKY_BRG_MNGEMENT,
* - LEAKY_UNDEFINED_11,
* - LEAKY_UNDEFINED_12,
* - LEAKY_UNDEFINED_13,
* - LEAKY_UNDEFINED_14,
* - LEAKY_UNDEFINED_15,
* - LEAKY_UNDEFINED_16,
* - LEAKY_UNDEFINED_17,
* - LEAKY_UNDEFINED_18,
* - LEAKY_UNDEFINED_19,
* - LEAKY_UNDEFINED_1A,
* - LEAKY_UNDEFINED_1B,
* - LEAKY_UNDEFINED_1C,
* - LEAKY_UNDEFINED_1D,
* - LEAKY_UNDEFINED_1E,
* - LEAKY_UNDEFINED_1F,
* - LEAKY_GMRP,
* - LEAKY_GVRP,
* - LEAKY_UNDEF_GARP_22,
* - LEAKY_UNDEF_GARP_23,
* - LEAKY_UNDEF_GARP_24,
* - LEAKY_UNDEF_GARP_25,
* - LEAKY_UNDEF_GARP_26,
* - LEAKY_UNDEF_GARP_27,
* - LEAKY_UNDEF_GARP_28,
* - LEAKY_UNDEF_GARP_29,
* - LEAKY_UNDEF_GARP_2A,
* - LEAKY_UNDEF_GARP_2B,
* - LEAKY_UNDEF_GARP_2C,
* - LEAKY_UNDEF_GARP_2D,
* - LEAKY_UNDEF_GARP_2E,
* - LEAKY_UNDEF_GARP_2F,
* - LEAKY_IGMP,
* - LEAKY_IPMULTICAST.
* - LEAKY_CDP,
* - LEAKY_CSSTP,
* - LEAKY_LLDP.
*/
extern rtk_api_ret_t rtk_leaky_portIsolation_get(rtk_leaky_type_t type, rtk_enable_t *pEnable);
#endif /* __RTK_API_LEAKY_H__ */

View file

@ -0,0 +1,481 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* Purpose : RTL8367/RTL8367C switch high-level API
*
* Feature : The file includes LED module high-layer API defination
*
*/
#ifndef __RTK_API_LED_H__
#define __RTK_API_LED_H__
typedef enum rtk_led_operation_e
{
LED_OP_SCAN=0,
LED_OP_PARALLEL,
LED_OP_SERIAL,
LED_OP_END,
}rtk_led_operation_t;
typedef enum rtk_led_active_e
{
LED_ACTIVE_HIGH=0,
LED_ACTIVE_LOW,
LED_ACTIVE_END,
}rtk_led_active_t;
typedef enum rtk_led_config_e
{
LED_CONFIG_LEDOFF=0,
LED_CONFIG_DUPCOL,
LED_CONFIG_LINK_ACT,
LED_CONFIG_SPD1000,
LED_CONFIG_SPD100,
LED_CONFIG_SPD10,
LED_CONFIG_SPD1000ACT,
LED_CONFIG_SPD100ACT,
LED_CONFIG_SPD10ACT,
LED_CONFIG_SPD10010ACT,
LED_CONFIG_LOOPDETECT,
LED_CONFIG_EEE,
LED_CONFIG_LINKRX,
LED_CONFIG_LINKTX,
LED_CONFIG_MASTER,
LED_CONFIG_ACT,
LED_CONFIG_END,
}rtk_led_congig_t;
typedef struct rtk_led_ability_s
{
rtk_enable_t link_10m;
rtk_enable_t link_100m;
rtk_enable_t link_500m;
rtk_enable_t link_1000m;
rtk_enable_t act_rx;
rtk_enable_t act_tx;
}rtk_led_ability_t;
typedef enum rtk_led_blink_rate_e
{
LED_BLINKRATE_32MS=0,
LED_BLINKRATE_64MS,
LED_BLINKRATE_128MS,
LED_BLINKRATE_256MS,
LED_BLINKRATE_512MS,
LED_BLINKRATE_1024MS,
LED_BLINKRATE_48MS,
LED_BLINKRATE_96MS,
LED_BLINKRATE_END,
}rtk_led_blink_rate_t;
typedef enum rtk_led_group_e
{
LED_GROUP_0 = 0,
LED_GROUP_1,
LED_GROUP_2,
LED_GROUP_END
}rtk_led_group_t;
typedef enum rtk_led_force_mode_e
{
LED_FORCE_NORMAL=0,
LED_FORCE_BLINK,
LED_FORCE_OFF,
LED_FORCE_ON,
LED_FORCE_END
}rtk_led_force_mode_t;
typedef enum rtk_led_serialOutput_e
{
SERIAL_LED_NONE = 0,
SERIAL_LED_0,
SERIAL_LED_0_1,
SERIAL_LED_0_2,
SERIAL_LED_END,
}rtk_led_serialOutput_t;
/* Function Name:
* rtk_led_enable_set
* Description:
* Set Led enable congiuration
* Input:
* group - LED group id.
* pPortmask - LED enable port mask.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The API can be used to enable LED per port per group.
*/
extern rtk_api_ret_t rtk_led_enable_set(rtk_led_group_t group, rtk_portmask_t *pPortmask);
/* Function Name:
* rtk_led_enable_get
* Description:
* Get Led enable congiuration
* Input:
* group - LED group id.
* Output:
* pPortmask - LED enable port mask.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The API can be used to get LED enable status.
*/
extern rtk_api_ret_t rtk_led_enable_get(rtk_led_group_t group, rtk_portmask_t *pPortmask);
/* Function Name:
* rtk_led_operation_set
* Description:
* Set Led operation mode
* Input:
* mode - LED operation mode.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The API can set Led operation mode.
* The modes that can be set are as following:
* - LED_OP_SCAN,
* - LED_OP_PARALLEL,
* - LED_OP_SERIAL,
*/
extern rtk_api_ret_t rtk_led_operation_set(rtk_led_operation_t mode);
/* Function Name:
* rtk_led_operation_get
* Description:
* Get Led operation mode
* Input:
* None
* Output:
* pMode - Support LED operation mode.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The API can get Led operation mode.
* The modes that can be set are as following:
* - LED_OP_SCAN,
* - LED_OP_PARALLEL,
* - LED_OP_SERIAL,
*/
extern rtk_api_ret_t rtk_led_operation_get(rtk_led_operation_t *pMode);
/* Function Name:
* rtk_led_modeForce_set
* Description:
* Set Led group to congiuration force mode
* Input:
* port - port ID
* group - Support LED group id.
* mode - Support LED force mode.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_PORT_ID - Error Port ID
* Note:
* The API can force to one force mode.
* The force modes that can be set are as following:
* - LED_FORCE_NORMAL,
* - LED_FORCE_BLINK,
* - LED_FORCE_OFF,
* - LED_FORCE_ON.
*/
extern rtk_api_ret_t rtk_led_modeForce_set(rtk_port_t port, rtk_led_group_t group, rtk_led_force_mode_t mode);
/* Function Name:
* rtk_led_modeForce_get
* Description:
* Get Led group to congiuration force mode
* Input:
* port - port ID
* group - Support LED group id.
* pMode - Support LED force mode.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_PORT_ID - Error Port ID
* Note:
* The API can get forced Led group mode.
* The force modes that can be set are as following:
* - LED_FORCE_NORMAL,
* - LED_FORCE_BLINK,
* - LED_FORCE_OFF,
* - LED_FORCE_ON.
*/
extern rtk_api_ret_t rtk_led_modeForce_get(rtk_port_t port, rtk_led_group_t group, rtk_led_force_mode_t *pMode);
/* Function Name:
* rtk_led_blinkRate_set
* Description:
* Set LED blinking rate
* Input:
* blinkRate - blinking rate.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* ASIC support 6 types of LED blinking rates at 43ms, 84ms, 120ms, 170ms, 340ms and 670ms.
*/
extern rtk_api_ret_t rtk_led_blinkRate_set(rtk_led_blink_rate_t blinkRate);
/* Function Name:
* rtk_led_blinkRate_get
* Description:
* Get LED blinking rate at mode 0 to mode 3
* Input:
* None
* Output:
* pBlinkRate - blinking rate.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* There are 6 types of LED blinking rates at 43ms, 84ms, 120ms, 170ms, 340ms and 670ms.
*/
extern rtk_api_ret_t rtk_led_blinkRate_get(rtk_led_blink_rate_t *pBlinkRate);
/* Function Name:
* rtk_led_groupConfig_set
* Description:
* Set per group Led to congiuration mode
* Input:
* group - LED group.
* config - LED configuration
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The API can set LED indicated information configuration for each LED group with 1 to 1 led mapping to each port.
* - Definition LED Statuses Description
* - 0000 LED_Off LED pin Tri-State.
* - 0001 Dup/Col Collision, Full duplex Indicator.
* - 0010 Link/Act Link, Activity Indicator.
* - 0011 Spd1000 1000Mb/s Speed Indicator.
* - 0100 Spd100 100Mb/s Speed Indicator.
* - 0101 Spd10 10Mb/s Speed Indicator.
* - 0110 Spd1000/Act 1000Mb/s Speed/Activity Indicator.
* - 0111 Spd100/Act 100Mb/s Speed/Activity Indicator.
* - 1000 Spd10/Act 10Mb/s Speed/Activity Indicator.
* - 1001 Spd100 (10)/Act 10/100Mb/s Speed/Activity Indicator.
* - 1010 LoopDetect LoopDetect Indicator.
* - 1011 EEE EEE Indicator.
* - 1100 Link/Rx Link, Activity Indicator.
* - 1101 Link/Tx Link, Activity Indicator.
* - 1110 Master Link on Master Indicator.
* - 1111 Act Activity Indicator. Low for link established.
*/
extern rtk_api_ret_t rtk_led_groupConfig_set(rtk_led_group_t group, rtk_led_congig_t config);
/* Function Name:
* rtk_led_groupConfig_get
* Description:
* Get Led group congiuration mode
* Input:
* group - LED group.
* Output:
* pConfig - LED configuration.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The API can get LED indicated information configuration for each LED group.
*/
extern rtk_api_ret_t rtk_led_groupConfig_get(rtk_led_group_t group, rtk_led_congig_t *pConfig);
/* Function Name:
* rtk_led_groupAbility_set
* Description:
* Configure per group Led ability
* Input:
* group - LED group.
* pAbility - LED ability
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* None.
*/
extern rtk_api_ret_t rtk_led_groupAbility_set(rtk_led_group_t group, rtk_led_ability_t *pAbility);
/* Function Name:
* rtk_led_groupAbility_get
* Description:
* Get per group Led ability
* Input:
* group - LED group.
* pAbility - LED ability
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* None.
*/
extern rtk_api_ret_t rtk_led_groupAbility_get(rtk_led_group_t group, rtk_led_ability_t *pAbility);
/* Function Name:
* rtk_led_serialMode_set
* Description:
* Set Led serial mode active congiuration
* Input:
* active - LED group.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The API can set LED serial mode active congiuration.
*/
extern rtk_api_ret_t rtk_led_serialMode_set(rtk_led_active_t active);
/* Function Name:
* rtk_led_serialMode_get
* Description:
* Get Led group congiuration mode
* Input:
* group - LED group.
* Output:
* pConfig - LED configuration.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The API can get LED serial mode active configuration.
*/
extern rtk_api_ret_t rtk_led_serialMode_get(rtk_led_active_t *pActive);
/* Function Name:
* rtk_led_OutputEnable_set
* Description:
* This API set LED I/O state.
* Input:
* enabled - LED I/O state
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Error parameter
* Note:
* This API set LED I/O state.
*/
extern rtk_api_ret_t rtk_led_OutputEnable_set(rtk_enable_t state);
/* Function Name:
* rtk_led_OutputEnable_get
* Description:
* This API get LED I/O state.
* Input:
* None.
* Output:
* pEnabled - LED I/O state
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Error parameter
* Note:
* This API set current LED I/O state.
*/
extern rtk_api_ret_t rtk_led_OutputEnable_get(rtk_enable_t *pState);
/* Function Name:
* rtk_led_serialModePortmask_set
* Description:
* This API configure Serial LED output Group and portmask
* Input:
* output - output group
* pPortmask - output portmask
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Error parameter
* Note:
* None.
*/
extern rtk_api_ret_t rtk_led_serialModePortmask_set(rtk_led_serialOutput_t output, rtk_portmask_t *pPortmask);
/* Function Name:
* rtk_led_serialModePortmask_get
* Description:
* This API get Serial LED output Group and portmask
* Input:
* None.
* Output:
* pOutput - output group
* pPortmask - output portmask
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Error parameter
* Note:
* None.
*/
extern rtk_api_ret_t rtk_led_serialModePortmask_get(rtk_led_serialOutput_t *pOutput, rtk_portmask_t *pPortmask);
#endif /* __RTK_API_LED_H__ */

View file

@ -0,0 +1,272 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* Purpose : RTL8367/RTL8367C switch high-level API
*
* Feature : The file includes Mirror module high-layer API defination
*
*/
#ifndef __RTK_API_MIRROR_H__
#define __RTK_API_MIRROR_H__
typedef enum rtk_mirror_keep_e
{
MIRROR_FOLLOW_VLAN = 0,
MIRROR_KEEP_ORIGINAL,
MIRROR_KEEP_END
}rtk_mirror_keep_t;
/* Function Name:
* rtk_mirror_portBased_set
* Description:
* Set port mirror function.
* Input:
* mirroring_port - Monitor port.
* pMirrored_rx_portmask - Rx mirror port mask.
* pMirrored_tx_portmask - Tx mirror port mask.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number
* RT_ERR_PORT_MASK - Invalid portmask.
* Note:
* The API is to set mirror function of source port and mirror port.
* The mirror port can only be set to one port and the TX and RX mirror ports
* should be identical.
*/
extern rtk_api_ret_t rtk_mirror_portBased_set(rtk_port_t mirroring_port, rtk_portmask_t *pMirrored_rx_portmask, rtk_portmask_t *pMirrored_tx_portmask);
/* Function Name:
* rtk_mirror_portBased_get
* Description:
* Get port mirror function.
* Input:
* None
* Output:
* pMirroring_port - Monitor port.
* pMirrored_rx_portmask - Rx mirror port mask.
* pMirrored_tx_portmask - Tx mirror port mask.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The API is to get mirror function of source port and mirror port.
*/
extern rtk_api_ret_t rtk_mirror_portBased_get(rtk_port_t* pMirroring_port, rtk_portmask_t *pMirrored_rx_portmask, rtk_portmask_t *pMirrored_tx_portmask);
/* Function Name:
* rtk_mirror_portIso_set
* Description:
* Set mirror port isolation.
* Input:
* enable |Mirror isolation status.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_ENABLE - Invalid enable input
* Note:
* The API is to set mirror isolation function that prevent normal forwarding packets to miror port.
*/
extern rtk_api_ret_t rtk_mirror_portIso_set(rtk_enable_t enable);
/* Function Name:
* rtk_mirror_portIso_get
* Description:
* Get mirror port isolation.
* Input:
* None
* Output:
* pEnable |Mirror isolation status.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The API is to get mirror isolation status.
*/
extern rtk_api_ret_t rtk_mirror_portIso_get(rtk_enable_t *pEnable);
/* Function Name:
* rtk_mirror_vlanLeaky_set
* Description:
* Set mirror VLAN leaky.
* Input:
* txenable -TX leaky enable.
* rxenable - RX leaky enable.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_ENABLE - Invalid enable input
* Note:
* The API is to set mirror VLAN leaky function forwarding packets to miror port.
*/
extern rtk_api_ret_t rtk_mirror_vlanLeaky_set(rtk_enable_t txenable, rtk_enable_t rxenable);
/* Function Name:
* rtk_mirror_vlanLeaky_get
* Description:
* Get mirror VLAN leaky.
* Input:
* None
* Output:
* pTxenable - TX leaky enable.
* pRxenable - RX leaky enable.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The API is to get mirror VLAN leaky status.
*/
extern rtk_api_ret_t rtk_mirror_vlanLeaky_get(rtk_enable_t *pTxenable, rtk_enable_t *pRxenable);
/* Function Name:
* rtk_mirror_isolationLeaky_set
* Description:
* Set mirror Isolation leaky.
* Input:
* txenable -TX leaky enable.
* rxenable - RX leaky enable.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_ENABLE - Invalid enable input
* Note:
* The API is to set mirror VLAN leaky function forwarding packets to miror port.
*/
extern rtk_api_ret_t rtk_mirror_isolationLeaky_set(rtk_enable_t txenable, rtk_enable_t rxenable);
/* Function Name:
* rtk_mirror_isolationLeaky_get
* Description:
* Get mirror isolation leaky.
* Input:
* None
* Output:
* pTxenable - TX leaky enable.
* pRxenable - RX leaky enable.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The API is to get mirror isolation leaky status.
*/
extern rtk_api_ret_t rtk_mirror_isolationLeaky_get(rtk_enable_t *pTxenable, rtk_enable_t *pRxenable);
/* Function Name:
* rtk_mirror_keep_set
* Description:
* Set mirror packet format keep.
* Input:
* mode - -mirror keep mode.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_ENABLE - Invalid enable input
* Note:
* The API is to set -mirror keep mode.
* The mirror keep mode is as following:
* - MIRROR_FOLLOW_VLAN
* - MIRROR_KEEP_ORIGINAL
* - MIRROR_KEEP_END
*/
extern rtk_api_ret_t rtk_mirror_keep_set(rtk_mirror_keep_t mode);
/* Function Name:
* rtk_mirror_keep_get
* Description:
* Get mirror packet format keep.
* Input:
* None
* Output:
* pMode -mirror keep mode.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The API is to get mirror keep mode.
* The mirror keep mode is as following:
* - MIRROR_FOLLOW_VLAN
* - MIRROR_KEEP_ORIGINAL
* - MIRROR_KEEP_END
*/
extern rtk_api_ret_t rtk_mirror_keep_get(rtk_mirror_keep_t *pMode);
/* Function Name:
* rtk_mirror_override_set
* Description:
* Set port mirror override function.
* Input:
* rxMirror - 1: output mirrored packet, 0: output normal forward packet
* txMirror - 1: output mirrored packet, 0: output normal forward packet
* aclMirror - 1: output mirrored packet, 0: output normal forward packet
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
* The API is to set mirror override function.
* This function control the output format when a port output
* normal forward & mirrored packet at the same time.
*/
extern rtk_api_ret_t rtk_mirror_override_set(rtk_enable_t rxMirror, rtk_enable_t txMirror, rtk_enable_t aclMirror);
/* Function Name:
* rtk_mirror_override_get
* Description:
* Get port mirror override function.
* Input:
* None
* Output:
* pRxMirror - 1: output mirrored packet, 0: output normal forward packet
* pTxMirror - 1: output mirrored packet, 0: output normal forward packet
* pAclMirror - 1: output mirrored packet, 0: output normal forward packet
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_NULL_POINTER - Null Pointer
* Note:
* The API is to Get mirror override function.
* This function control the output format when a port output
* normal forward & mirrored packet at the same time.
*/
extern rtk_api_ret_t rtk_mirror_override_get(rtk_enable_t *pRxMirror, rtk_enable_t *pTxMirror, rtk_enable_t *pAclMirror);
#endif /* __RTK_API_MIRROR_H__ */

View file

@ -0,0 +1,188 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* $Revision: 76306 $
* $Date: 2017-03-08 15:13:58 +0800 (, 08 2017) $
*
* Purpose : RTL8367/RTL8367C switch high-level API
*
* Feature : The file includes the following modules and sub-modules
* (1) OAM (802.3ah) configuration
*
*/
#ifndef __RTK_OAM_H__
#define __RTK_OAM_H__
/*
* Symbol Definition
*/
/*
* Data Declaration
*/
/*
* Macro Declaration
*/
typedef enum rtk_oam_parser_act_e
{
OAM_PARSER_ACTION_FORWARD = 0,
OAM_PARSER_ACTION_LOOPBACK,
OAM_PARSER_ACTION_DISCARD,
OAM_PARSER_ACTION_END,
} rtk_oam_parser_act_t;
typedef enum rtk_oam_multiplexer_act_e
{
OAM_MULTIPLEXER_ACTION_FORWARD = 0,
OAM_MULTIPLEXER_ACTION_DISCARD,
OAM_MULTIPLEXER_ACTION_CPUONLY,
OAM_MULTIPLEXER_ACTION_END,
} rtk_oam_multiplexer_act_t;
/*
* Function Declaration
*/
/* Function Name:
* rtk_oam_init
* Description:
* Initialize oam module.
* Input:
* None
* Output:
* None
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* Note:
* Must initialize oam module before calling any oam APIs.
*/
extern rtk_api_ret_t rtk_oam_init(void);
/* Function Name:
* rtk_oam_state_set
* Description:
* This API set OAM state.
* Input:
* enabled -OAMstate
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Error parameter
* Note:
* This API set OAM state.
*/
extern rtk_api_ret_t rtk_oam_state_set(rtk_enable_t enabled);
/* Function Name:
* rtk_oam_state_get
* Description:
* This API get OAM state.
* Input:
* None.
* Output:
* pEnabled - H/W IGMP state
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Error parameter
* Note:
* This API set current OAM state.
*/
extern rtk_api_ret_t rtk_oam_state_get(rtk_enable_t *pEnabled);
/* Module Name : OAM */
/* Function Name:
* rtk_oam_parserAction_set
* Description:
* Set OAM parser action
* Input:
* port - port id
* action - parser action
* Output:
* None
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_PORT_ID - invalid port id
* Note:
* None
*/
extern rtk_api_ret_t rtk_oam_parserAction_set(rtk_port_t port, rtk_oam_parser_act_t action);
/* Function Name:
* rtk_oam_parserAction_set
* Description:
* Get OAM parser action
* Input:
* port - port id
* Output:
* pAction - parser action
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_PORT_ID - invalid port id
* Note:
* None
*/
extern rtk_api_ret_t rtk_oam_parserAction_get(rtk_port_t port, rtk_oam_parser_act_t *pAction);
/* Function Name:
* rtk_oam_multiplexerAction_set
* Description:
* Set OAM multiplexer action
* Input:
* port - port id
* action - parser action
* Output:
* None
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_PORT_ID - invalid port id
* Note:
* None
*/
extern rtk_api_ret_t rtk_oam_multiplexerAction_set(rtk_port_t port, rtk_oam_multiplexer_act_t action);
/* Function Name:
* rtk_oam_multiplexerAction_set
* Description:
* Get OAM multiplexer action
* Input:
* port - port id
* Output:
* pAction - parser action
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_PORT_ID - invalid port id
* Note:
* None
*/
extern rtk_api_ret_t rtk_oam_multiplexerAction_get(rtk_port_t port, rtk_oam_multiplexer_act_t *pAction);
#endif /* __RTK_OAM_H__ */

View file

@ -0,0 +1,959 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* Purpose : RTL8367/RTL8367C switch high-level API
*
* Feature : The file includes port module high-layer API defination
*
*/
#ifndef __RTK_API_PORT_H__
#define __RTK_API_PORT_H__
/*
* Data Type Declaration
*/
#define PHY_CONTROL_REG 0
#define PHY_STATUS_REG 1
#define PHY_AN_ADVERTISEMENT_REG 4
#define PHY_AN_LINKPARTNER_REG 5
#define PHY_1000_BASET_CONTROL_REG 9
#define PHY_1000_BASET_STATUS_REG 10
#define PHY_RESOLVED_REG 26
#define RTK_EFID_MAX 0x7
#define RTK_FIBER_FORCE_1000M 3
#define RTK_FIBER_FORCE_100M 5
#define RTK_FIBER_FORCE_100M1000M 7
#define RTK_INDRECT_ACCESS_CRTL 0x1f00
#define RTK_INDRECT_ACCESS_STATUS 0x1f01
#define RTK_INDRECT_ACCESS_ADDRESS 0x1f02
#define RTK_INDRECT_ACCESS_WRITE_DATA 0x1f03
#define RTK_INDRECT_ACCESS_READ_DATA 0x1f04
#define RTK_INDRECT_ACCESS_DELAY 0x1f80
#define RTK_INDRECT_ACCESS_BURST 0x1f81
#define RTK_RW_MASK 0x2
#define RTK_CMD_MASK 0x1
#define RTK_PHY_BUSY_OFFSET 2
typedef enum rtk_mode_ext_e
{
MODE_EXT_DISABLE = 0,
MODE_EXT_RGMII,
MODE_EXT_MII_MAC,
MODE_EXT_MII_PHY,
MODE_EXT_TMII_MAC,
MODE_EXT_TMII_PHY,
MODE_EXT_GMII,
MODE_EXT_RMII_MAC,
MODE_EXT_RMII_PHY,
MODE_EXT_SGMII,
MODE_EXT_HSGMII,
MODE_EXT_1000X_100FX,
MODE_EXT_1000X,
MODE_EXT_100FX,
MODE_EXT_RGMII_2,
MODE_EXT_MII_MAC_2,
MODE_EXT_MII_PHY_2,
MODE_EXT_TMII_MAC_2,
MODE_EXT_TMII_PHY_2,
MODE_EXT_RMII_MAC_2,
MODE_EXT_RMII_PHY_2,
MODE_EXT_END
} rtk_mode_ext_t;
typedef enum rtk_port_duplex_e
{
PORT_HALF_DUPLEX = 0,
PORT_FULL_DUPLEX,
PORT_DUPLEX_END
} rtk_port_duplex_t;
typedef enum rtk_port_linkStatus_e
{
PORT_LINKDOWN = 0,
PORT_LINKUP,
PORT_LINKSTATUS_END
} rtk_port_linkStatus_t;
typedef struct rtk_port_mac_ability_s
{
rtk_uint32 forcemode;
rtk_uint32 speed;
rtk_uint32 duplex;
rtk_uint32 link;
rtk_uint32 nway;
rtk_uint32 txpause;
rtk_uint32 rxpause;
}rtk_port_mac_ability_t;
typedef struct rtk_port_phy_ability_s
{
rtk_uint32 AutoNegotiation; /*PHY register 0.12 setting for auto-negotiation process*/
rtk_uint32 Half_10; /*PHY register 4.5 setting for 10BASE-TX half duplex capable*/
rtk_uint32 Full_10; /*PHY register 4.6 setting for 10BASE-TX full duplex capable*/
rtk_uint32 Half_100; /*PHY register 4.7 setting for 100BASE-TX half duplex capable*/
rtk_uint32 Full_100; /*PHY register 4.8 setting for 100BASE-TX full duplex capable*/
rtk_uint32 Full_1000; /*PHY register 9.9 setting for 1000BASE-T full duplex capable*/
rtk_uint32 FC; /*PHY register 4.10 setting for flow control capability*/
rtk_uint32 AsyFC; /*PHY register 4.11 setting for asymmetric flow control capability*/
} rtk_port_phy_ability_t;
typedef rtk_uint32 rtk_port_phy_data_t; /* phy page */
typedef enum rtk_port_phy_mdix_mode_e
{
PHY_AUTO_CROSSOVER_MODE= 0,
PHY_FORCE_MDI_MODE,
PHY_FORCE_MDIX_MODE,
PHY_FORCE_MODE_END
} rtk_port_phy_mdix_mode_t;
typedef enum rtk_port_phy_mdix_status_e
{
PHY_STATUS_AUTO_MDI_MODE= 0,
PHY_STATUS_AUTO_MDIX_MODE,
PHY_STATUS_FORCE_MDI_MODE,
PHY_STATUS_FORCE_MDIX_MODE,
PHY_STATUS_FORCE_MODE_END
} rtk_port_phy_mdix_status_t;
typedef rtk_uint32 rtk_port_phy_page_t; /* phy page */
typedef enum rtk_port_phy_reg_e
{
PHY_REG_CONTROL = 0,
PHY_REG_STATUS,
PHY_REG_IDENTIFIER_1,
PHY_REG_IDENTIFIER_2,
PHY_REG_AN_ADVERTISEMENT,
PHY_REG_AN_LINKPARTNER,
PHY_REG_1000_BASET_CONTROL = 9,
PHY_REG_1000_BASET_STATUS,
PHY_REG_END = 32
} rtk_port_phy_reg_t;
typedef enum rtk_port_phy_test_mode_e
{
PHY_TEST_MODE_NORMAL= 0,
PHY_TEST_MODE_1,
PHY_TEST_MODE_2,
PHY_TEST_MODE_3,
PHY_TEST_MODE_4,
PHY_TEST_MODE_END
} rtk_port_phy_test_mode_t;
typedef enum rtk_port_speed_e
{
PORT_SPEED_10M = 0,
PORT_SPEED_100M,
PORT_SPEED_1000M,
PORT_SPEED_500M,
PORT_SPEED_2500M,
PORT_SPEED_END
} rtk_port_speed_t;
typedef enum rtk_port_media_e
{
PORT_MEDIA_COPPER = 0,
PORT_MEDIA_FIBER,
PORT_MEDIA_END
}rtk_port_media_t;
typedef struct rtk_rtctResult_s
{
rtk_port_speed_t linkType;
union
{
struct fe_result_s
{
rtk_uint32 isRxShort;
rtk_uint32 isTxShort;
rtk_uint32 isRxOpen;
rtk_uint32 isTxOpen;
rtk_uint32 isRxMismatch;
rtk_uint32 isTxMismatch;
rtk_uint32 isRxLinedriver;
rtk_uint32 isTxLinedriver;
rtk_uint32 rxLen;
rtk_uint32 txLen;
} fe_result;
struct ge_result_s
{
rtk_uint32 channelAShort;
rtk_uint32 channelBShort;
rtk_uint32 channelCShort;
rtk_uint32 channelDShort;
rtk_uint32 channelAOpen;
rtk_uint32 channelBOpen;
rtk_uint32 channelCOpen;
rtk_uint32 channelDOpen;
rtk_uint32 channelAMismatch;
rtk_uint32 channelBMismatch;
rtk_uint32 channelCMismatch;
rtk_uint32 channelDMismatch;
rtk_uint32 channelALinedriver;
rtk_uint32 channelBLinedriver;
rtk_uint32 channelCLinedriver;
rtk_uint32 channelDLinedriver;
rtk_uint32 channelALen;
rtk_uint32 channelBLen;
rtk_uint32 channelCLen;
rtk_uint32 channelDLen;
} ge_result;
}result;
} rtk_rtctResult_t;
/* Function Name:
* rtk_port_phyAutoNegoAbility_set
* Description:
* Set ethernet PHY auto-negotiation desired ability.
* Input:
* port - port id.
* pAbility - Ability structure
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_PHY_REG_ID - Invalid PHY address
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy
* Note:
* If Full_1000 bit is set to 1, the AutoNegotiation will be automatic set to 1. While both AutoNegotiation and Full_1000 are set to 0, the PHY speed and duplex selection will
* be set as following 100F > 100H > 10F > 10H priority sequence.
*/
extern rtk_api_ret_t rtk_port_phyAutoNegoAbility_set(rtk_port_t port, rtk_port_phy_ability_t *pAbility);
/* Function Name:
* rtk_port_phyAutoNegoAbility_get
* Description:
* Get PHY ability through PHY registers.
* Input:
* port - Port id.
* Output:
* pAbility - Ability structure
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_PHY_REG_ID - Invalid PHY address
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy
* Note:
* Get the capablity of specified PHY.
*/
extern rtk_api_ret_t rtk_port_phyAutoNegoAbility_get(rtk_port_t port, rtk_port_phy_ability_t *pAbility);
/* Function Name:
* rtk_port_phyForceModeAbility_set
* Description:
* Set the port speed/duplex mode/pause/asy_pause in the PHY force mode.
* Input:
* port - port id.
* pAbility - Ability structure
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_PHY_REG_ID - Invalid PHY address
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy
* Note:
* While both AutoNegotiation and Full_1000 are set to 0, the PHY speed and duplex selection will
* be set as following 100F > 100H > 10F > 10H priority sequence.
*/
extern rtk_api_ret_t rtk_port_phyForceModeAbility_set(rtk_port_t port, rtk_port_phy_ability_t *pAbility);
/* Function Name:
* rtk_port_phyForceModeAbility_get
* Description:
* Get PHY ability through PHY registers.
* Input:
* port - Port id.
* Output:
* pAbility - Ability structure
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_PHY_REG_ID - Invalid PHY address
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy
* Note:
* Get the capablity of specified PHY.
*/
extern rtk_api_ret_t rtk_port_phyForceModeAbility_get(rtk_port_t port, rtk_port_phy_ability_t *pAbility);
/* Function Name:
* rtk_port_phyStatus_get
* Description:
* Get ethernet PHY linking status
* Input:
* port - Port id.
* Output:
* linkStatus - PHY link status
* speed - PHY link speed
* duplex - PHY duplex mode
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_PHY_REG_ID - Invalid PHY address
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy
* Note:
* API will return auto negotiation status of phy.
*/
extern rtk_api_ret_t rtk_port_phyStatus_get(rtk_port_t port, rtk_port_linkStatus_t *pLinkStatus, rtk_port_speed_t *pSpeed, rtk_port_duplex_t *pDuplex);
/* Function Name:
* rtk_port_macForceLink_set
* Description:
* Set port force linking configuration.
* Input:
* port - port id.
* pPortability - port ability configuration
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* Note:
* This API can set Port/MAC force mode properties.
*/
extern rtk_api_ret_t rtk_port_macForceLink_set(rtk_port_t port, rtk_port_mac_ability_t *pPortability);
/* Function Name:
* rtk_port_macForceLink_get
* Description:
* Get port force linking configuration.
* Input:
* port - Port id.
* Output:
* pPortability - port ability configuration
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* This API can get Port/MAC force mode properties.
*/
extern rtk_api_ret_t rtk_port_macForceLink_get(rtk_port_t port, rtk_port_mac_ability_t *pPortability);
/* Function Name:
* rtk_port_macForceLinkExt_set
* Description:
* Set external interface force linking configuration.
* Input:
* port - external port ID
* mode - external interface mode
* pPortability - port ability configuration
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* This API can set external interface force mode properties.
* The external interface can be set to:
* - MODE_EXT_DISABLE,
* - MODE_EXT_RGMII,
* - MODE_EXT_MII_MAC,
* - MODE_EXT_MII_PHY,
* - MODE_EXT_TMII_MAC,
* - MODE_EXT_TMII_PHY,
* - MODE_EXT_GMII,
* - MODE_EXT_RMII_MAC,
* - MODE_EXT_RMII_PHY,
* - MODE_EXT_SGMII,
* - MODE_EXT_HSGMII,
* - MODE_EXT_1000X_100FX,
* - MODE_EXT_1000X,
* - MODE_EXT_100FX,
*/
extern rtk_api_ret_t rtk_port_macForceLinkExt_set(rtk_port_t port, rtk_mode_ext_t mode, rtk_port_mac_ability_t *pPortability);
/* Function Name:
* rtk_port_macForceLinkExt_get
* Description:
* Set external interface force linking configuration.
* Input:
* port - external port ID
* Output:
* pMode - external interface mode
* pPortability - port ability configuration
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* This API can get external interface force mode properties.
*/
extern rtk_api_ret_t rtk_port_macForceLinkExt_get(rtk_port_t port, rtk_mode_ext_t *pMode, rtk_port_mac_ability_t *pPortability);
/* Function Name:
* rtk_port_macStatus_get
* Description:
* Get port link status.
* Input:
* port - Port id.
* Output:
* pPortstatus - port ability configuration
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* Note:
* This API can get Port/PHY properties.
*/
extern rtk_api_ret_t rtk_port_macStatus_get(rtk_port_t port, rtk_port_mac_ability_t *pPortstatus);
/* Function Name:
* rtk_port_macLocalLoopbackEnable_set
* Description:
* Set Port Local Loopback. (Redirect TX to RX.)
* Input:
* port - Port id.
* enable - Loopback state, 0:disable, 1:enable
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* Note:
* This API can enable/disable Local loopback in MAC.
* For UTP port, This API will also enable the digital
* loopback bit in PHY register for sync of speed between
* PHY and MAC. For EXT port, users need to force the
* link state by themself.
*/
extern rtk_api_ret_t rtk_port_macLocalLoopbackEnable_set(rtk_port_t port, rtk_enable_t enable);
/* Function Name:
* rtk_port_macLocalLoopbackEnable_get
* Description:
* Get Port Local Loopback. (Redirect TX to RX.)
* Input:
* port - Port id.
* Output:
* pEnable - Loopback state, 0:disable, 1:enable
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* Note:
* None.
*/
extern rtk_api_ret_t rtk_port_macLocalLoopbackEnable_get(rtk_port_t port, rtk_enable_t *pEnable);
/* Function Name:
* rtk_port_phyReg_set
* Description:
* Set PHY register data of the specific port.
* Input:
* port - port id.
* reg - Register id
* regData - Register data
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_PHY_REG_ID - Invalid PHY address
* RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy
* Note:
* This API can set PHY register data of the specific port.
*/
extern rtk_api_ret_t rtk_port_phyReg_set(rtk_port_t port, rtk_port_phy_reg_t reg, rtk_port_phy_data_t value);
/* Function Name:
* rtk_port_phyReg_get
* Description:
* Get PHY register data of the specific port.
* Input:
* port - Port id.
* reg - Register id
* Output:
* pData - Register data
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_PHY_REG_ID - Invalid PHY address
* RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy
* Note:
* This API can get PHY register data of the specific port.
*/
extern rtk_api_ret_t rtk_port_phyReg_get(rtk_port_t port, rtk_port_phy_reg_t reg, rtk_port_phy_data_t *pData);
/* Function Name:
* rtk_port_backpressureEnable_set
* Description:
* Set the half duplex backpressure enable status of the specific port.
* Input:
* port - port id.
* enable - Back pressure status.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_ENABLE - Invalid enable input.
* Note:
* This API can set the half duplex backpressure enable status of the specific port.
* The half duplex backpressure enable status of the port is as following:
* - DISABLE
* - ENABLE
*/
extern rtk_api_ret_t rtk_port_backpressureEnable_set(rtk_port_t port, rtk_enable_t enable);
/* Function Name:
* rtk_port_backpressureEnable_get
* Description:
* Get the half duplex backpressure enable status of the specific port.
* Input:
* port - Port id.
* Output:
* pEnable - Back pressure status.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* Note:
* This API can get the half duplex backpressure enable status of the specific port.
* The half duplex backpressure enable status of the port is as following:
* - DISABLE
* - ENABLE
*/
extern rtk_api_ret_t rtk_port_backpressureEnable_get(rtk_port_t port, rtk_enable_t *pEnable);
/* Function Name:
* rtk_port_adminEnable_set
* Description:
* Set port admin configuration of the specific port.
* Input:
* port - port id.
* enable - Back pressure status.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_ENABLE - Invalid enable input.
* Note:
* This API can set port admin configuration of the specific port.
* The port admin configuration of the port is as following:
* - DISABLE
* - ENABLE
*/
extern rtk_api_ret_t rtk_port_adminEnable_set(rtk_port_t port, rtk_enable_t enable);
/* Function Name:
* rtk_port_adminEnable_get
* Description:
* Get port admin configurationof the specific port.
* Input:
* port - Port id.
* Output:
* pEnable - Back pressure status.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* Note:
* This API can get port admin configuration of the specific port.
* The port admin configuration of the port is as following:
* - DISABLE
* - ENABLE
*/
extern rtk_api_ret_t rtk_port_adminEnable_get(rtk_port_t port, rtk_enable_t *pEnable);
/* Function Name:
* rtk_port_isolation_set
* Description:
* Set permitted port isolation portmask
* Input:
* port - port id.
* pPortmask - Permit port mask
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_PORT_MASK - Invalid portmask.
* Note:
* This API set the port mask that a port can trasmit packet to of each port
* A port can only transmit packet to ports included in permitted portmask
*/
extern rtk_api_ret_t rtk_port_isolation_set(rtk_port_t port, rtk_portmask_t *pPortmask);
/* Function Name:
* rtk_port_isolation_get
* Description:
* Get permitted port isolation portmask
* Input:
* port - Port id.
* Output:
* pPortmask - Permit port mask
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* Note:
* This API get the port mask that a port can trasmit packet to of each port
* A port can only transmit packet to ports included in permitted portmask
*/
extern rtk_api_ret_t rtk_port_isolation_get(rtk_port_t port, rtk_portmask_t *pPortmask);
/* Function Name:
* rtk_port_rgmiiDelayExt_set
* Description:
* Set RGMII interface delay value for TX and RX.
* Input:
* txDelay - TX delay value, 1 for delay 2ns and 0 for no-delay
* rxDelay - RX delay value, 0~7 for delay setup.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* This API can set external interface 2 RGMII delay.
* In TX delay, there are 2 selection: no-delay and 2ns delay.
* In RX dekay, there are 8 steps for delay tunning. 0 for no-delay, and 7 for maximum delay.
*/
extern rtk_api_ret_t rtk_port_rgmiiDelayExt_set(rtk_port_t port, rtk_data_t txDelay, rtk_data_t rxDelay);
/* Function Name:
* rtk_port_rgmiiDelayExt_get
* Description:
* Get RGMII interface delay value for TX and RX.
* Input:
* None
* Output:
* pTxDelay - TX delay value
* pRxDelay - RX delay value
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* This API can set external interface 2 RGMII delay.
* In TX delay, there are 2 selection: no-delay and 2ns delay.
* In RX dekay, there are 8 steps for delay tunning. 0 for n0-delay, and 7 for maximum delay.
*/
extern rtk_api_ret_t rtk_port_rgmiiDelayExt_get(rtk_port_t port, rtk_data_t *pTxDelay, rtk_data_t *pRxDelay);
/* Function Name:
* rtk_port_phyEnableAll_set
* Description:
* Set all PHY enable status.
* Input:
* enable - PHY Enable State.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_ENABLE - Invalid enable input.
* Note:
* This API can set all PHY status.
* The configuration of all PHY is as following:
* - DISABLE
* - ENABLE
*/
extern rtk_api_ret_t rtk_port_phyEnableAll_set(rtk_enable_t enable);
/* Function Name:
* rtk_port_phyEnableAll_get
* Description:
* Get all PHY enable status.
* Input:
* None
* Output:
* pEnable - PHY Enable State.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
* This API can set all PHY status.
* The configuration of all PHY is as following:
* - DISABLE
* - ENABLE
*/
extern rtk_api_ret_t rtk_port_phyEnableAll_get(rtk_enable_t *pEnable);
/* Function Name:
* rtk_port_efid_set
* Description:
* Set port-based enhanced filtering database
* Input:
* port - Port id.
* efid - Specified enhanced filtering database.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_L2_FID - Invalid fid.
* RT_ERR_INPUT - Invalid input parameter.
* RT_ERR_PORT_ID - Invalid port ID.
* Note:
* The API can set port-based enhanced filtering database.
*/
extern rtk_api_ret_t rtk_port_efid_set(rtk_port_t port, rtk_data_t efid);
/* Function Name:
* rtk_port_efid_get
* Description:
* Get port-based enhanced filtering database
* Input:
* port - Port id.
* Output:
* pEfid - Specified enhanced filtering database.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_PORT_ID - Invalid port ID.
* Note:
* The API can get port-based enhanced filtering database status.
*/
extern rtk_api_ret_t rtk_port_efid_get(rtk_port_t port, rtk_data_t *pEfid);
/* Function Name:
* rtk_port_phyComboPortMedia_set
* Description:
* Set Combo port media type
* Input:
* port - Port id. (Should be Port 4)
* media - Media (COPPER or FIBER)
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_PORT_ID - Invalid port ID.
* Note:
* The API can Set Combo port media type.
*/
extern rtk_api_ret_t rtk_port_phyComboPortMedia_set(rtk_port_t port, rtk_port_media_t media);
/* Function Name:
* rtk_port_phyComboPortMedia_get
* Description:
* Get Combo port media type
* Input:
* port - Port id. (Should be Port 4)
* Output:
* pMedia - Media (COPPER or FIBER)
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_PORT_ID - Invalid port ID.
* Note:
* The API can Set Combo port media type.
*/
extern rtk_api_ret_t rtk_port_phyComboPortMedia_get(rtk_port_t port, rtk_port_media_t *pMedia);
/* Function Name:
* rtk_port_rtctEnable_set
* Description:
* Enable RTCT test
* Input:
* pPortmask - Port mask of RTCT enabled port
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_MASK - Invalid port mask.
* Note:
* The API can enable RTCT Test
*/
extern rtk_api_ret_t rtk_port_rtctEnable_set(rtk_portmask_t *pPortmask);
/* Function Name:
* rtk_port_rtctDisable_set
* Description:
* Disable RTCT test
* Input:
* pPortmask - Port mask of RTCT disabled port
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_MASK - Invalid port mask.
* Note:
* The API can disable RTCT Test
*/
rtk_api_ret_t rtk_port_rtctDisable_set(rtk_portmask_t *pPortmask);
/* Function Name:
* rtk_port_rtctResult_get
* Description:
* Get the result of RTCT test
* Input:
* port - Port ID
* Output:
* pRtctResult - The result of RTCT result
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port ID.
* RT_ERR_PHY_RTCT_NOT_FINISH - Testing does not finish.
* Note:
* The API can get RTCT test result.
* RTCT test may takes 4.8 seconds to finish its test at most.
* Thus, if this API return RT_ERR_PHY_RTCT_NOT_FINISH or
* other error code, the result can not be referenced and
* user should call this API again until this API returns
* a RT_ERR_OK.
* The result is stored at pRtctResult->ge_result
* pRtctResult->linkType is unused.
* The unit of channel length is 2.5cm. Ex. 300 means 300 * 2.5 = 750cm = 7.5M
*/
extern rtk_api_ret_t rtk_port_rtctResult_get(rtk_port_t port, rtk_rtctResult_t *pRtctResult);
/* Function Name:
* rtk_port_sds_reset
* Description:
* Reset Serdes
* Input:
* port - Port ID
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port ID.
* Note:
* The API can reset Serdes
*/
extern rtk_api_ret_t rtk_port_sds_reset(rtk_port_t port);
/* Function Name:
* rtk_port_sgmiiLinkStatus_get
* Description:
* Get SGMII status
* Input:
* port - Port ID
* Output:
* pSignalDetect - Signal detect
* pSync - Sync
* pLink - Link
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port ID.
* Note:
* The API can reset Serdes
*/
extern rtk_api_ret_t rtk_port_sgmiiLinkStatus_get(rtk_port_t port, rtk_data_t *pSignalDetect, rtk_data_t *pSync, rtk_port_linkStatus_t *pLink);
/* Function Name:
* rtk_port_sgmiiNway_set
* Description:
* Configure SGMII/HSGMII port Nway state
* Input:
* port - Port ID
* state - Nway state
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port ID.
* Note:
* The API configure SGMII/HSGMII port Nway state
*/
extern rtk_api_ret_t rtk_port_sgmiiNway_set(rtk_port_t port, rtk_enable_t state);
/* Function Name:
* rtk_port_sgmiiNway_get
* Description:
* Get SGMII/HSGMII port Nway state
* Input:
* port - Port ID
* Output:
* pState - Nway state
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port ID.
* Note:
* The API can get SGMII/HSGMII port Nway state
*/
extern rtk_api_ret_t rtk_port_sgmiiNway_get(rtk_port_t port, rtk_enable_t *pState);
#endif /* __RTK_API_PORT_H__ */

View file

@ -0,0 +1,511 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* Purpose : RTL8367/RTL8367C switch high-level API
*
* Feature : The file includes time module high-layer API defination
*
*/
#ifndef __RTK_API_PTP_H__
#define __RTK_API_PTP_H__
/*
* Symbol Definition
*/
#define RTK_MAX_NUM_OF_NANO_SECOND 0x3B9AC9FF
#define RTK_PTP_INTR_MASK 0xFF
#define RTK_MAX_NUM_OF_TPID 0xFFFF
/* Message Type */
typedef enum rtk_ptp_msgType_e
{
PTP_MSG_TYPE_TX_SYNC = 0,
PTP_MSG_TYPE_TX_DELAY_REQ,
PTP_MSG_TYPE_TX_PDELAY_REQ,
PTP_MSG_TYPE_TX_PDELAY_RESP,
PTP_MSG_TYPE_RX_SYNC,
PTP_MSG_TYPE_RX_DELAY_REQ,
PTP_MSG_TYPE_RX_PDELAY_REQ,
PTP_MSG_TYPE_RX_PDELAY_RESP,
PTP_MSG_TYPE_END
} rtk_ptp_msgType_t;
typedef enum rtk_ptp_intType_e
{
PTP_INT_TYPE_TX_SYNC = 0,
PTP_INT_TYPE_TX_DELAY_REQ,
PTP_INT_TYPE_TX_PDELAY_REQ,
PTP_INT_TYPE_TX_PDELAY_RESP,
PTP_INT_TYPE_RX_SYNC,
PTP_INT_TYPE_RX_DELAY_REQ,
PTP_INT_TYPE_RX_PDELAY_REQ,
PTP_INT_TYPE_RX_PDELAY_RESP,
PTP_INT_TYPE_ALL,
PTP_INT_TYPE_END
}rtk_ptp_intType_t;
typedef enum rtk_ptp_sys_adjust_e
{
SYS_ADJUST_PLUS = 0,
SYS_ADJUST_MINUS,
SYS_ADJUST_END
} rtk_ptp_sys_adjust_t;
/* Reference Time */
typedef struct rtk_ptp_timeStamp_s
{
rtk_uint32 sec;
rtk_uint32 nsec;
} rtk_ptp_timeStamp_t;
typedef struct rtk_ptp_info_s
{
rtk_uint32 sequenceId;
rtk_ptp_timeStamp_t timeStamp;
} rtk_ptp_info_t;
typedef rtk_uint32 rtk_ptp_tpid_t;
typedef rtk_uint32 rtk_ptp_intStatus_t; /* interrupt status mask */
/*
* Data Declaration
*/
/*
* Function Declaration
*/
/* Function Name:
* rtk_time_init
* Description:
* PTP function initialization.
* Input:
* None
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
* This API is used to initialize EEE status.
*/
extern rtk_api_ret_t rtk_ptp_init(void);
/* Function Name:
* rtk_ptp_mac_set
* Description:
* Configure PTP mac address.
* Input:
* mac - mac address to parser PTP packets.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameter.
* Note:
* None
*/
extern rtk_api_ret_t rtk_ptp_mac_set(rtk_mac_t mac);
/* Function Name:
* rtk_ptp_mac_get
* Description:
* Get PTP mac address.
* Input:
* None
* Output:
* pMac - mac address to parser PTP packets.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameter.
* Note:
* None
*/
extern rtk_api_ret_t rtk_ptp_mac_get(rtk_mac_t *pMac);
/* Function Name:
* rtk_ptp_tpid_set
* Description:
* Configure PTP accepted outer & inner tag TPID.
* Input:
* outerId - Ether type of S-tag frame parsing in PTP ports.
* innerId - Ether type of C-tag frame parsing in PTP ports.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameter.
* Note:
* None
*/
extern rtk_api_ret_t rtk_ptp_tpid_set(rtk_ptp_tpid_t outerId, rtk_ptp_tpid_t innerId);
/* Function Name:
* rtk_ptp_tpid_get
* Description:
* Get PTP accepted outer & inner tag TPID.
* Input:
* None
* Output:
* pOuterId - Ether type of S-tag frame parsing in PTP ports.
* pInnerId - Ether type of C-tag frame parsing in PTP ports.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
* None
*/
extern rtk_api_ret_t rtk_ptp_tpid_get(rtk_ptp_tpid_t *pOuterId, rtk_ptp_tpid_t *pInnerId);
/* Function Name:
* rtk_ptp_refTime_set
* Description:
* Set the reference time of the specified device.
* Input:
* timeStamp - reference timestamp value
* Output:
* None
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_INPUT - invalid input parameter
* Applicable:
* 8390, 8380
* Note:
* None
*/
extern rtk_api_ret_t rtk_ptp_refTime_set(rtk_ptp_timeStamp_t timeStamp);
/* Function Name:
* rtk_ptp_refTime_get
* Description:
* Get the reference time of the specified device.
* Input:
* Output:
* pTimeStamp - pointer buffer of the reference time
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_UNIT_ID - invalid unit id
* RT_ERR_NOT_INIT - The module is not initial
* RT_ERR_NULL_POINTER - input parameter may be null pointer
* Applicable:
* 8390, 8380
* Note:
* None
*/
extern rtk_api_ret_t rtk_ptp_refTime_get(rtk_ptp_timeStamp_t *pTimeStamp);
/* Function Name:
* rtk_ptp_refTimeAdjust_set
* Description:
* Adjust the reference time.
* Input:
* unit - unit id
* sign - significant
* timeStamp - reference timestamp value
* Output:
* None
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_UNIT_ID - invalid unit id
* RT_ERR_NOT_INIT - The module is not initial
* RT_ERR_INPUT - invalid input parameter
* Note:
* sign=0 for positive adjustment, sign=1 for negative adjustment.
*/
extern rtk_api_ret_t rtk_ptp_refTimeAdjust_set(rtk_ptp_sys_adjust_t sign, rtk_ptp_timeStamp_t timeStamp);
/* Function Name:
* rtk_ptp_refTimeEnable_set
* Description:
* Set the enable state of reference time of the specified device.
* Input:
* enable - status
* Output:
* None
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_INPUT - invalid input parameter
* Note:
* None
*/
extern rtk_api_ret_t rtk_ptp_refTimeEnable_set(rtk_enable_t enable);
/* Function Name:
* rtk_ptp_refTimeEnable_get
* Description:
* Get the enable state of reference time of the specified device.
* Input:
* Output:
* pEnable - status
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_UNIT_ID - invalid unit id
* RT_ERR_NOT_INIT - The module is not initial
* RT_ERR_NULL_POINTER - input parameter may be null pointer
* Applicable:
* 8390, 8380
* Note:
* None
*/
extern rtk_api_ret_t rtk_ptp_refTimeEnable_get(rtk_enable_t *pEnable);
/* Function Name:
* rtk_ptp_portEnable_set
* Description:
* Set PTP status of the specified port.
* Input:
* port - port id
* enable - status
* Output:
* None
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_PORT - invalid port id
* RT_ERR_INPUT - invalid input parameter
* Note:
* None
*/
extern rtk_api_ret_t rtk_ptp_portEnable_set(rtk_port_t port, rtk_enable_t enable);
/* Function Name:
* rtk_ptp_portEnable_get
* Description:
* Get PTP status of the specified port.
* Input:
* port - port id
* Output:
* pEnable - status
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_PORT - invalid port id
* RT_ERR_NULL_POINTER - input parameter may be null pointer
* Note:
* None
*/
extern rtk_api_ret_t rtk_ptp_portEnable_get(rtk_port_t port, rtk_enable_t *pEnable);
/* Function Name:
* rtk_ptp_portTimestamp_get
* Description:
* Get PTP timstamp according to the PTP identifier on the dedicated port from the specified device.
* Input:
* unit - unit id
* port - port id
* type - PTP message type
* Output:
* pInfo - pointer buffer of sequence ID and timestamp
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_PORT_ID - invalid port id
* RT_ERR_INPUT - invalid input parameter
* RT_ERR_NULL_POINTER - input parameter may be null pointer
* Applicable:
* 8390, 8380
* Note:
* None
*/
extern rtk_api_ret_t rtk_ptp_portTimestamp_get( rtk_port_t port, rtk_ptp_msgType_t type, rtk_ptp_info_t *pInfo);
/* Function Name:
* rtk_ptp_intControl_set
* Description:
* Set PTP interrupt trigger status configuration.
* Input:
* type - Interrupt type.
* enable - Interrupt status.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_ENABLE - Invalid enable input.
* Note:
* The API can set PTP interrupt status configuration.
* The interrupt trigger status is shown in the following:
* PTP_INT_TYPE_TX_SYNC = 0,
* PTP_INT_TYPE_TX_DELAY_REQ,
* PTP_INT_TYPE_TX_PDELAY_REQ,
* PTP_INT_TYPE_TX_PDELAY_RESP,
* PTP_INT_TYPE_RX_SYNC,
* PTP_INT_TYPE_RX_DELAY_REQ,
* PTP_INT_TYPE_RX_PDELAY_REQ,
* PTP_INT_TYPE_RX_PDELAY_RESP,
* PTP_INT_TYPE_ALL,
*/
extern rtk_api_ret_t rtk_ptp_intControl_set(rtk_ptp_intType_t type, rtk_enable_t enable);
/* Function Name:
* rtk_ptp_intControl_get
* Description:
* Get PTP interrupt trigger status configuration.
* Input:
* type - Interrupt type.
* Output:
* pEnable - Interrupt status.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The API can get interrupt status configuration.
* The interrupt trigger status is shown in the following:
* PTP_INT_TYPE_TX_SYNC = 0,
* PTP_INT_TYPE_TX_DELAY_REQ,
* PTP_INT_TYPE_TX_PDELAY_REQ,
* PTP_INT_TYPE_TX_PDELAY_RESP,
* PTP_INT_TYPE_RX_SYNC,
* PTP_INT_TYPE_RX_DELAY_REQ,
* PTP_INT_TYPE_RX_PDELAY_REQ,
* PTP_INT_TYPE_RX_PDELAY_RESP,
*/
extern rtk_api_ret_t rtk_ptp_intControl_get(rtk_ptp_intType_t type, rtk_enable_t *pEnable);
/* Function Name:
* rtk_ptp_intStatus_get
* Description:
* Get PTP port interrupt trigger status.
* Input:
* port - physical port
* Output:
* pStatusMask - Interrupt status bit mask.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The API can get interrupt trigger status when interrupt happened.
* The interrupt trigger status is shown in the following:
* - PORT 0 INT (value[0] (Bit0))
* - PORT 1 INT (value[0] (Bit1))
* - PORT 2 INT (value[0] (Bit2))
* - PORT 3 INT (value[0] (Bit3))
* - PORT 4 INT (value[0] (Bit4))
*
*/
extern rtk_api_ret_t rtk_ptp_intStatus_get(rtk_ptp_intStatus_t *pStatusMask);
/* Function Name:
* rtk_ptp_portIntStatus_set
* Description:
* Set PTP port interrupt trigger status to clean.
* Input:
* port - physical port
* statusMask - Interrupt status bit mask.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The API can clean interrupt trigger status when interrupt happened.
* The interrupt trigger status is shown in the following:
* - PTP_INT_TYPE_TX_SYNC (value[0] (Bit0))
* - PTP_INT_TYPE_TX_DELAY_REQ (value[0] (Bit1))
* - PTP_INT_TYPE_TX_PDELAY_REQ (value[0] (Bit2))
* - PTP_INT_TYPE_TX_PDELAY_RESP (value[0] (Bit3))
* - PTP_INT_TYPE_RX_SYNC (value[0] (Bit4))
* - PTP_INT_TYPE_RX_DELAY_REQ (value[0] (Bit5))
* - PTP_INT_TYPE_RX_PDELAY_REQ (value[0] (Bit6))
* - PTP_INT_TYPE_RX_PDELAY_RESP (value[0] (Bit7))
* The status will be cleared after execute this API.
*/
extern rtk_api_ret_t rtk_ptp_portIntStatus_set(rtk_port_t port, rtk_ptp_intStatus_t statusMask);
/* Function Name:
* rtk_ptp_portIntStatus_get
* Description:
* Get PTP port interrupt trigger status.
* Input:
* port - physical port
* Output:
* pStatusMask - Interrupt status bit mask.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The API can get interrupt trigger status when interrupt happened.
* The interrupt trigger status is shown in the following:
* - PTP_INT_TYPE_TX_SYNC (value[0] (Bit0))
* - PTP_INT_TYPE_TX_DELAY_REQ (value[0] (Bit1))
* - PTP_INT_TYPE_TX_PDELAY_REQ (value[0] (Bit2))
* - PTP_INT_TYPE_TX_PDELAY_RESP (value[0] (Bit3))
* - PTP_INT_TYPE_RX_SYNC (value[0] (Bit4))
* - PTP_INT_TYPE_RX_DELAY_REQ (value[0] (Bit5))
* - PTP_INT_TYPE_RX_PDELAY_REQ (value[0] (Bit6))
* - PTP_INT_TYPE_RX_PDELAY_RESP (value[0] (Bit7))
*
*/
extern rtk_api_ret_t rtk_ptp_portIntStatus_get(rtk_port_t port, rtk_ptp_intStatus_t *pStatusMask);
/* Function Name:
* rtk_ptp_portPtpTrap_set
* Description:
* Set PTP packet trap of the specified port.
* Input:
* port - port id
* enable - status
* Output:
* None
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_PORT - invalid port id
* RT_ERR_INPUT - invalid input parameter
* Note:
* None
*/
extern rtk_api_ret_t rtk_ptp_portTrap_set(rtk_port_t port, rtk_enable_t enable);
/* Function Name:
* rtk_ptp_portPtpEnable_get
* Description:
* Get PTP packet trap of the specified port.
* Input:
* port - port id
* Output:
* pEnable - status
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_PORT - invalid port id
* RT_ERR_NULL_POINTER - input parameter may be null pointer
* Note:
* None
*/
extern rtk_api_ret_t rtk_ptp_portTrap_get(rtk_port_t port, rtk_enable_t *pEnable);
#endif /* __RTK_API_PTP_H__ */

View file

@ -0,0 +1,781 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* Purpose : RTL8367/RTL8367C switch high-level API
*
* Feature : The file includes QoS module high-layer API defination
*
*/
#ifndef __RTK_API_QOS_H__
#define __RTK_API_QOS_H__
/*
* Data Type Declaration
*/
#define QOS_DEFAULT_TICK_PERIOD (19-1)
#define QOS_DEFAULT_BYTE_PER_TOKEN 34
#define QOS_DEFAULT_LK_THRESHOLD (34*3) /* Why use 0x400? */
#define QOS_DEFAULT_INGRESS_BANDWIDTH 0x3FFF /* 0x3FFF => unlimit */
#define QOS_DEFAULT_EGRESS_BANDWIDTH 0x3D08 /*( 0x3D08 + 1) * 64Kbps => 1Gbps*/
#define QOS_DEFAULT_PREIFP 1
#define QOS_DEFAULT_PACKET_USED_PAGES_FC 0x60
#define QOS_DEFAULT_PACKET_USED_FC_EN 0
#define QOS_DEFAULT_QUEUE_BASED_FC_EN 1
#define QOS_DEFAULT_PRIORITY_SELECT_PORT 8
#define QOS_DEFAULT_PRIORITY_SELECT_1Q 0
#define QOS_DEFAULT_PRIORITY_SELECT_ACL 0
#define QOS_DEFAULT_PRIORITY_SELECT_DSCP 0
#define QOS_DEFAULT_DSCP_MAPPING_PRIORITY 0
#define QOS_DEFAULT_1Q_REMARKING_ABILITY 0
#define QOS_DEFAULT_DSCP_REMARKING_ABILITY 0
#define QOS_DEFAULT_QUEUE_GAP 20
#define QOS_DEFAULT_QUEUE_NO_MAX 6
#define QOS_DEFAULT_AVERAGE_PACKET_RATE 0x3FFF
#define QOS_DEFAULT_BURST_SIZE_IN_APR 0x3F
#define QOS_DEFAULT_PEAK_PACKET_RATE 2
#define QOS_DEFAULT_SCHEDULER_ABILITY_APR 1 /*disable*/
#define QOS_DEFAULT_SCHEDULER_ABILITY_PPR 1 /*disable*/
#define QOS_DEFAULT_SCHEDULER_ABILITY_WFQ 1 /*disable*/
#define QOS_WEIGHT_MAX 127
#define RTK_MAX_NUM_OF_PRIORITY 8
#define RTK_MAX_NUM_OF_QUEUE 8
#define RTK_PRIMAX 7
#define RTK_QIDMAX 7
#define RTK_DSCPMAX 63
/* enum Priority Selection Index */
typedef enum rtk_qos_priDecTbl_e
{
PRIDECTBL_IDX0 = 0,
PRIDECTBL_IDX1,
PRIDECTBL_END,
}rtk_qos_priDecTbl_t;
/* Types of 802.1p remarking source */
typedef enum rtk_qos_1pRmkSrc_e
{
DOT1P_RMK_SRC_USER_PRI,
DOT1P_RMK_SRC_TAG_PRI,
DOT1P_RMK_SRC_END
} rtk_qos_1pRmkSrc_t;
/* Types of DSCP remarking source */
typedef enum rtk_qos_dscpRmkSrc_e
{
DSCP_RMK_SRC_INT_PRI,
DSCP_RMK_SRC_DSCP,
DSCP_RMK_SRC_USER_PRI,
DSCP_RMK_SRC_END
} rtk_qos_dscpRmkSrc_t;
typedef struct rtk_priority_select_s
{
rtk_uint32 port_pri;
rtk_uint32 dot1q_pri;
rtk_uint32 acl_pri;
rtk_uint32 dscp_pri;
rtk_uint32 cvlan_pri;
rtk_uint32 svlan_pri;
rtk_uint32 dmac_pri;
rtk_uint32 smac_pri;
} rtk_priority_select_t;
typedef struct rtk_qos_pri2queue_s
{
rtk_uint32 pri2queue[RTK_MAX_NUM_OF_PRIORITY];
} rtk_qos_pri2queue_t;
typedef struct rtk_qos_queue_weights_s
{
rtk_uint32 weights[RTK_MAX_NUM_OF_QUEUE];
} rtk_qos_queue_weights_t;
typedef enum rtk_qos_scheduling_type_e
{
WFQ = 0, /* Weighted-Fair-Queue */
WRR, /* Weighted-Round-Robin */
SCHEDULING_TYPE_END
} rtk_qos_scheduling_type_t;
typedef rtk_uint32 rtk_queue_num_t; /* queue number*/
/* Function Name:
* rtk_qos_init
* Description:
* Configure Qos default settings with queue number assigment to each port.
* Input:
* queueNum - Queue number of each port.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_QUEUE_NUM - Invalid queue number.
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* This API will initialize related Qos setting with queue number assigment.
* The queue number is from 1 to 8.
*/
extern rtk_api_ret_t rtk_qos_init(rtk_queue_num_t queueNum);
/* Function Name:
* rtk_qos_priSel_set
* Description:
* Configure the priority order among different priority mechanism.
* Input:
* index - Priority decision table index (0~1)
* pPriDec - Priority assign for port, dscp, 802.1p, cvlan, svlan, acl based priority decision.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_QOS_SEL_PRI_SOURCE - Invalid priority decision source parameter.
* Note:
* ASIC will follow user priority setting of mechanisms to select mapped queue priority for receiving frame.
* If two priority mechanisms are the same, the ASIC will chose the highest priority from mechanisms to
* assign queue priority to receiving frame.
* The priority sources are:
* - PRIDEC_PORT
* - PRIDEC_ACL
* - PRIDEC_DSCP
* - PRIDEC_1Q
* - PRIDEC_1AD
* - PRIDEC_CVLAN
* - PRIDEC_DA
* - PRIDEC_SA
*/
extern rtk_api_ret_t rtk_qos_priSel_set(rtk_qos_priDecTbl_t index, rtk_priority_select_t *pPriDec);
/* Function Name:
* rtk_qos_priSel_get
* Description:
* Get the priority order configuration among different priority mechanism.
* Input:
* index - Priority decision table index (0~1)
* Output:
* pPriDec - Priority assign for port, dscp, 802.1p, cvlan, svlan, acl based priority decision .
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
* ASIC will follow user priority setting of mechanisms to select mapped queue priority for receiving frame.
* If two priority mechanisms are the same, the ASIC will chose the highest priority from mechanisms to
* assign queue priority to receiving frame.
* The priority sources are:
* - PRIDEC_PORT,
* - PRIDEC_ACL,
* - PRIDEC_DSCP,
* - PRIDEC_1Q,
* - PRIDEC_1AD,
* - PRIDEC_CVLAN,
* - PRIDEC_DA,
* - PRIDEC_SA,
*/
extern rtk_api_ret_t rtk_qos_priSel_get(rtk_qos_priDecTbl_t index, rtk_priority_select_t *pPriDec);
/* Function Name:
* rtk_qos_1pPriRemap_set
* Description:
* Configure 1Q priorities mapping to internal absolute priority.
* Input:
* dot1p_pri - 802.1p priority value.
* int_pri - internal priority value.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_VLAN_PRIORITY - Invalid 1p priority.
* RT_ERR_QOS_INT_PRIORITY - Invalid priority.
* Note:
* Priority of 802.1Q assignment for internal asic priority, and it is used for queue usage and packet scheduling.
*/
extern rtk_api_ret_t rtk_qos_1pPriRemap_set(rtk_pri_t dot1p_pri, rtk_pri_t int_pri);
/* Function Name:
* rtk_qos_1pPriRemap_get
* Description:
* Get 1Q priorities mapping to internal absolute priority.
* Input:
* dot1p_pri - 802.1p priority value .
* Output:
* pInt_pri - internal priority value.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_VLAN_PRIORITY - Invalid priority.
* RT_ERR_QOS_INT_PRIORITY - Invalid priority.
* Note:
* Priority of 802.1Q assigment for internal asic priority, and it is uesed for queue usage and packet scheduling.
*/
extern rtk_api_ret_t rtk_qos_1pPriRemap_get(rtk_pri_t dot1p_pri, rtk_pri_t *pInt_pri);
/* Function Name:
* rtk_qos_1pRemarkSrcSel_set
* Description:
* Set remarking source of 802.1p remarking.
* Input:
* type - remarking source
* Output:
* None
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_NOT_INIT - The module is not initial
* RT_ERR_PORT_ID - invalid port id
* RT_ERR_INPUT - invalid input parameter
* Note:
* The API can configure 802.1p remark functionality to map original 802.1p value or internal
* priority to TX DSCP value.
*/
extern rtk_api_ret_t rtk_qos_1pRemarkSrcSel_set(rtk_qos_1pRmkSrc_t type);
/* Function Name:
* rtk_qos_1pRemarkSrcSel_get
* Description:
* Get remarking source of 802.1p remarking.
* Input:
* none
* Output:
* pType - remarking source
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_NOT_INIT - The module is not initial
* RT_ERR_PORT_ID - invalid port id
* RT_ERR_INPUT - invalid input parameter
* RT_ERR_NULL_POINTER - input parameter may be null pointer
* Note:
* None
*/
extern rtk_api_ret_t rtk_qos_1pRemarkSrcSel_get(rtk_qos_1pRmkSrc_t *pType);
/* Function Name:
* rtk_qos_dscpPriRemap_set
* Description:
* Map dscp value to internal priority.
* Input:
* dscp - Dscp value of receiving frame
* int_pri - internal priority value .
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_QOS_DSCP_VALUE - Invalid DSCP value.
* RT_ERR_QOS_INT_PRIORITY - Invalid priority.
* Note:
* The Differentiated Service Code Point is a selector for router's per-hop behaviors. As a selector, there is no implication that a numerically
* greater DSCP implies a better network service. As can be seen, the DSCP totally overlaps the old precedence field of TOS. So if values of
* DSCP are carefully chosen then backward compatibility can be achieved.
*/
extern rtk_api_ret_t rtk_qos_dscpPriRemap_set(rtk_dscp_t dscp, rtk_pri_t int_pri);
/* Function Name:
* rtk_qos_dscpPriRemap_get
* Description:
* Get dscp value to internal priority.
* Input:
* dscp - Dscp value of receiving frame
* Output:
* pInt_pri - internal priority value.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_QOS_DSCP_VALUE - Invalid DSCP value.
* Note:
* The Differentiated Service Code Point is a selector for router's per-hop behaviors. As a selector, there is no implication that a numerically
* greater DSCP implies a better network service. As can be seen, the DSCP totally overlaps the old precedence field of TOS. So if values of
* DSCP are carefully chosen then backward compatibility can be achieved.
*/
extern rtk_api_ret_t rtk_qos_dscpPriRemap_get(rtk_dscp_t dscp, rtk_pri_t *pInt_pri);
/* Function Name:
* rtk_qos_portPri_set
* Description:
* Configure priority usage to each port.
* Input:
* port - Port id.
* int_pri - internal priority value.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_QOS_SEL_PORT_PRI - Invalid port priority.
* RT_ERR_QOS_INT_PRIORITY - Invalid priority.
* Note:
* The API can set priority of port assignments for queue usage and packet scheduling.
*/
extern rtk_api_ret_t rtk_qos_portPri_set(rtk_port_t port, rtk_pri_t int_pri) ;
/* Function Name:
* rtk_qos_portPri_get
* Description:
* Get priority usage to each port.
* Input:
* port - Port id.
* Output:
* pInt_pri - internal priority value.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The API can get priority of port assignments for queue usage and packet scheduling.
*/
extern rtk_api_ret_t rtk_qos_portPri_get(rtk_port_t port, rtk_pri_t *pInt_pri) ;
/* Function Name:
* rtk_qos_queueNum_set
* Description:
* Set output queue number for each port.
* Input:
* port - Port id.
* index - Mapping queue number (1~8)
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_QUEUE_NUM - Invalid queue number.
* Note:
* The API can set the output queue number of the specified port. The queue number is from 1 to 8.
*/
extern rtk_api_ret_t rtk_qos_queueNum_set(rtk_port_t port, rtk_queue_num_t queue_num);
/* Function Name:
* rtk_qos_queueNum_get
* Description:
* Get output queue number.
* Input:
* port - Port id.
* Output:
* pQueue_num - Mapping queue number
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* Note:
* The API will return the output queue number of the specified port. The queue number is from 1 to 8.
*/
extern rtk_api_ret_t rtk_qos_queueNum_get(rtk_port_t port, rtk_queue_num_t *pQueue_num);
/* Function Name:
* rtk_qos_priMap_set
* Description:
* Set output queue number for each port.
* Input:
* queue_num - Queue number usage.
* pPri2qid - Priority mapping to queue ID.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_QUEUE_NUM - Invalid queue number.
* RT_ERR_QUEUE_ID - Invalid queue id.
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_QOS_INT_PRIORITY - Invalid priority.
* Note:
* ASIC supports priority mapping to queue with different queue number from 1 to 8.
* For different queue numbers usage, ASIC supports different internal available queue IDs.
*/
extern rtk_api_ret_t rtk_qos_priMap_set(rtk_queue_num_t queue_num, rtk_qos_pri2queue_t *pPri2qid);
/* Function Name:
* rtk_qos_priMap_get
* Description:
* Get priority to queue ID mapping table parameters.
* Input:
* queue_num - Queue number usage.
* Output:
* pPri2qid - Priority mapping to queue ID.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_QUEUE_NUM - Invalid queue number.
* Note:
* The API can return the mapping queue id of the specified priority and queue number.
* The queue number is from 1 to 8.
*/
extern rtk_api_ret_t rtk_qos_priMap_get(rtk_queue_num_t queue_num, rtk_qos_pri2queue_t *pPri2qid);
/* Function Name:
* rtk_qos_schedulingQueue_set
* Description:
* Set weight and type of queues in dedicated port.
* Input:
* port - Port id.
* pQweights - The array of weights for WRR/WFQ queue (0 for STRICT_PRIORITY queue).
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_QOS_QUEUE_WEIGHT - Invalid queue weight.
* Note:
* The API can set weight and type, strict priority or weight fair queue (WFQ) for
* dedicated port for using queues. If queue id is not included in queue usage,
* then its type and weight setting in dummy for setting. There are priorities
* as queue id in strict queues. It means strict queue id 5 carrying higher priority
* than strict queue id 4. The WFQ queue weight is from 1 to 128, and weight 0 is
* for strict priority queue type.
*/
extern rtk_api_ret_t rtk_qos_schedulingQueue_set(rtk_port_t port, rtk_qos_queue_weights_t *pQweights);
/* Function Name:
* rtk_qos_schedulingQueue_get
* Description:
* Get weight and type of queues in dedicated port.
* Input:
* port - Port id.
* Output:
* pQweights - The array of weights for WRR/WFQ queue (0 for STRICT_PRIORITY queue).
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_PORT_ID - Invalid port number.
* Note:
* The API can get weight and type, strict priority or weight fair queue (WFQ) for dedicated port for using queues.
* The WFQ queue weight is from 1 to 128, and weight 0 is for strict priority queue type.
*/
extern rtk_api_ret_t rtk_qos_schedulingQueue_get(rtk_port_t port, rtk_qos_queue_weights_t *pQweights);
/* Function Name:
* rtk_qos_1pRemarkEnable_set
* Description:
* Set 1p Remarking state
* Input:
* port - Port id.
* enable - State of per-port 1p Remarking
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_ENABLE - Invalid enable parameter.
* Note:
* The API can enable or disable 802.1p remarking ability for whole system.
* The status of 802.1p remark:
* - DISABLED
* - ENABLED
*/
extern rtk_api_ret_t rtk_qos_1pRemarkEnable_set(rtk_port_t port, rtk_enable_t enable);
/* Function Name:
* rtk_qos_1pRemarkEnable_get
* Description:
* Get 802.1p remarking ability.
* Input:
* port - Port id.
* Output:
* pEnable - Status of 802.1p remark.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* Note:
* The API can get 802.1p remarking ability.
* The status of 802.1p remark:
* - DISABLED
* - ENABLED
*/
extern rtk_api_ret_t rtk_qos_1pRemarkEnable_get(rtk_port_t port, rtk_enable_t *pEnable);
/* Function Name:
* rtk_qos_1pRemark_set
* Description:
* Set 802.1p remarking parameter.
* Input:
* int_pri - Internal priority value.
* dot1p_pri - 802.1p priority value.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_VLAN_PRIORITY - Invalid 1p priority.
* RT_ERR_QOS_INT_PRIORITY - Invalid priority.
* Note:
* The API can set 802.1p parameters source priority and new priority.
*/
extern rtk_api_ret_t rtk_qos_1pRemark_set(rtk_pri_t int_pri, rtk_pri_t dot1p_pri);
/* Function Name:
* rtk_qos_1pRemark_get
* Description:
* Get 802.1p remarking parameter.
* Input:
* int_pri - Internal priority value.
* Output:
* pDot1p_pri - 802.1p priority value.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_QOS_INT_PRIORITY - Invalid priority.
* Note:
* The API can get 802.1p remarking parameters. It would return new priority of ingress priority.
*/
extern rtk_api_ret_t rtk_qos_1pRemark_get(rtk_pri_t int_pri, rtk_pri_t *pDot1p_pri);
/* Function Name:
* rtk_qos_dscpRemarkEnable_set
* Description:
* Set DSCP remarking ability.
* Input:
* port - Port id.
* enable - status of DSCP remark.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_QOS_INT_PRIORITY - Invalid priority.
* RT_ERR_ENABLE - Invalid enable parameter.
* Note:
* The API can enable or disable DSCP remarking ability for whole system.
* The status of DSCP remark:
* - DISABLED
* - ENABLED
*/
extern rtk_api_ret_t rtk_qos_dscpRemarkEnable_set(rtk_port_t port, rtk_enable_t enable);
/* Function Name:
* rtk_qos_dscpRemarkEnable_get
* Description:
* Get DSCP remarking ability.
* Input:
* port - Port id.
* Output:
* pEnable - status of DSCP remarking.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* Note:
* The API can get DSCP remarking ability.
* The status of DSCP remark:
* - DISABLED
* - ENABLED
*/
extern rtk_api_ret_t rtk_qos_dscpRemarkEnable_get(rtk_port_t port, rtk_enable_t *pEnable);
/* Function Name:
* rtk_qos_dscpRemark_set
* Description:
* Set DSCP remarking parameter.
* Input:
* int_pri - Internal priority value.
* dscp - DSCP value.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_QOS_INT_PRIORITY - Invalid priority.
* RT_ERR_QOS_DSCP_VALUE - Invalid DSCP value.
* Note:
* The API can set DSCP value and mapping priority.
*/
extern rtk_api_ret_t rtk_qos_dscpRemark_set(rtk_pri_t int_pri, rtk_dscp_t dscp);
/* Function Name:
* rtk_qos_dscpRemark_get
* Description:
* Get DSCP remarking parameter.
* Input:
* int_pri - Internal priority value.
* Output:
* Dscp - DSCP value.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_QOS_INT_PRIORITY - Invalid priority.
* Note:
* The API can get DSCP parameters. It would return DSCP value for mapping priority.
*/
extern rtk_api_ret_t rtk_qos_dscpRemark_get(rtk_pri_t int_pri, rtk_dscp_t *pDscp);
/* Function Name:
* rtk_qos_dscpRemarkSrcSel_set
* Description:
* Set remarking source of DSCP remarking.
* Input:
* type - remarking source
* Output:
* None
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_NOT_INIT - The module is not initial
* RT_ERR_PORT_ID - invalid port id
* RT_ERR_INPUT - invalid input parameter
* Note:
* The API can configure DSCP remark functionality to map original DSCP value or internal
* priority to TX DSCP value.
*/
extern rtk_api_ret_t rtk_qos_dscpRemarkSrcSel_set(rtk_qos_dscpRmkSrc_t type);
/* Function Name:
* rtk_qos_dcpRemarkSrcSel_get
* Description:
* Get remarking source of DSCP remarking.
* Input:
* none
* Output:
* pType - remarking source
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_NOT_INIT - The module is not initial
* RT_ERR_PORT_ID - invalid port id
* RT_ERR_INPUT - invalid input parameter
* RT_ERR_NULL_POINTER - input parameter may be null pointer
* Note:
* None
*/
extern rtk_api_ret_t rtk_qos_dscpRemarkSrcSel_get(rtk_qos_dscpRmkSrc_t *pType);
/* Function Name:
* rtk_qos_dscpRemark2Dscp_set
* Description:
* Set DSCP to remarked DSCP mapping.
* Input:
* dscp - DSCP value
* rmkDscp - remarked DSCP value
* Output:
* None.
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_QOS_DSCP_VALUE - Invalid dscp value
* Note:
* dscp parameter can be DSCP value or internal priority according to configuration of API
* dal_apollomp_qos_dscpRemarkSrcSel_set(), because DSCP remark functionality can map original DSCP
* value or internal priority to TX DSCP value.
*/
extern rtk_api_ret_t rtk_qos_dscpRemark2Dscp_set(rtk_dscp_t dscp, rtk_dscp_t rmkDscp);
/* Function Name:
* rtk_qos_dscpRemark2Dscp_get
* Description:
* Get DSCP to remarked DSCP mapping.
* Input:
* dscp - DSCP value
* Output:
* pDscp - remarked DSCP value
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_QOS_DSCP_VALUE - Invalid dscp value
* RT_ERR_NULL_POINTER - NULL pointer
* Note:
* None.
*/
extern rtk_api_ret_t rtk_qos_dscpRemark2Dscp_get(rtk_dscp_t dscp, rtk_dscp_t *pDscp);
/* Function Name:
* rtk_qos_portPriSelIndex_set
* Description:
* Configure priority decision index to each port.
* Input:
* port - Port id.
* index - priority decision index.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_ENTRY_INDEX - Invalid entry index.
* Note:
* The API can set priority of port assignments for queue usage and packet scheduling.
*/
extern rtk_api_ret_t rtk_qos_portPriSelIndex_set(rtk_port_t port, rtk_qos_priDecTbl_t index);
/* Function Name:
* rtk_qos_portPriSelIndex_get
* Description:
* Get priority decision index from each port.
* Input:
* port - Port id.
* Output:
* pIndex - priority decision index.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* Note:
* The API can get priority of port assignments for queue usage and packet scheduling.
*/
extern rtk_api_ret_t rtk_qos_portPriSelIndex_get(rtk_port_t port, rtk_qos_priDecTbl_t *pIndex);
#endif /* __RTK_API_QOS_H__ */

View file

@ -0,0 +1,305 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* Purpose : RTL8367/RTL8367C switch high-level API
*
* Feature : The file includes rate module high-layer API defination
*
*/
#ifndef __RTK_API_RATE_H__
#define __RTK_API_RATE_H__
/*
* Include Files
*/
//#include <rtk_types.h>
/*
* Data Type Declaration
*/
#define RTK_MAX_METER_ID (rtk_switch_maxMeterId_get())
#define RTK_METER_NUM (RTK_MAX_METER_ID + 1)
typedef enum rtk_meter_type_e{
METER_TYPE_KBPS = 0, /* Kbps */
METER_TYPE_PPS, /* Packet per second */
METER_TYPE_END
}rtk_meter_type_t;
/*
* Function Declaration
*/
/* Rate */
/* Function Name:
* rtk_rate_shareMeter_set
* Description:
* Set meter configuration
* Input:
* index - shared meter index
* type - shared meter type
* rate - rate of share meter
* ifg_include - include IFG or not, ENABLE:include DISABLE:exclude
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_FILTER_METER_ID - Invalid meter
* RT_ERR_RATE - Invalid rate
* RT_ERR_INPUT - Invalid input parameters
* Note:
* The API can set shared meter rate and ifg include for each meter.
* The rate unit is 1 kbps and the range is from 8k to 1048568k if type is METER_TYPE_KBPS and
* the granularity of rate is 8 kbps.
* The rate unit is packets per second and the range is 1 ~ 0x1FFF if type is METER_TYPE_PPS.
* The ifg_include parameter is used
* for rate calculation with/without inter-frame-gap and preamble.
*/
rtk_api_ret_t rtk_rate_shareMeter_set(rtk_meter_id_t index, rtk_meter_type_t type, rtk_rate_t rate, rtk_enable_t ifg_include);
/* Function Name:
* rtk_rate_shareMeter_get
* Description:
* Get meter configuration
* Input:
* index - shared meter index
* Output:
* pType - Meter Type
* pRate - pointer of rate of share meter
* pIfg_include - include IFG or not, ENABLE:include DISABLE:exclude
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_FILTER_METER_ID - Invalid meter
* Note:
*
*/
rtk_api_ret_t rtk_rate_shareMeter_get(rtk_meter_id_t index, rtk_meter_type_t *pType, rtk_rate_t *pRate, rtk_enable_t *pIfg_include);
/* Function Name:
* rtk_rate_shareMeterBucket_set
* Description:
* Set meter Bucket Size
* Input:
* index - shared meter index
* bucket_size - Bucket Size
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_INPUT - Error Input
* RT_ERR_SMI - SMI access error
* RT_ERR_FILTER_METER_ID - Invalid meter
* Note:
* The API can set shared meter bucket size.
*/
extern rtk_api_ret_t rtk_rate_shareMeterBucket_set(rtk_meter_id_t index, rtk_uint32 bucket_size);
/* Function Name:
* rtk_rate_shareMeterBucket_get
* Description:
* Get meter Bucket Size
* Input:
* index - shared meter index
* Output:
* pBucket_size - Bucket Size
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_FILTER_METER_ID - Invalid meter
* Note:
* The API can get shared meter bucket size.
*/
extern rtk_api_ret_t rtk_rate_shareMeterBucket_get(rtk_meter_id_t index, rtk_uint32 *pBucket_size);
/* Function Name:
* rtk_rate_igrBandwidthCtrlRate_set
* Description:
* Set port ingress bandwidth control
* Input:
* port - Port id
* rate - Rate of share meter
* ifg_include - include IFG or not, ENABLE:include DISABLE:exclude
* fc_enable - enable flow control or not, ENABLE:use flow control DISABLE:drop
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_ENABLE - Invalid IFG parameter.
* RT_ERR_INBW_RATE - Invalid ingress rate parameter.
* Note:
* The rate unit is 1 kbps and the range is from 8k to 1048568k. The granularity of rate is 8 kbps.
* The ifg_include parameter is used for rate calculation with/without inter-frame-gap and preamble.
*/
extern rtk_api_ret_t rtk_rate_igrBandwidthCtrlRate_set( rtk_port_t port, rtk_rate_t rate, rtk_enable_t ifg_include, rtk_enable_t fc_enable);
/* Function Name:
* rtk_rate_igrBandwidthCtrlRate_get
* Description:
* Get port ingress bandwidth control
* Input:
* port - Port id
* Output:
* pRate - Rate of share meter
* pIfg_include - Rate's calculation including IFG, ENABLE:include DISABLE:exclude
* pFc_enable - enable flow control or not, ENABLE:use flow control DISABLE:drop
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The rate unit is 1 kbps and the range is from 8k to 1048568k. The granularity of rate is 8 kbps.
* The ifg_include parameter is used for rate calculation with/without inter-frame-gap and preamble.
*/
extern rtk_api_ret_t rtk_rate_igrBandwidthCtrlRate_get(rtk_port_t port, rtk_rate_t *pRate, rtk_enable_t *pIfg_include, rtk_enable_t *pFc_enable);
/* Function Name:
* rtk_rate_egrBandwidthCtrlRate_set
* Description:
* Set port egress bandwidth control
* Input:
* port - Port id
* rate - Rate of egress bandwidth
* ifg_include - include IFG or not, ENABLE:include DISABLE:exclude
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_QOS_EBW_RATE - Invalid egress bandwidth/rate
* Note:
* The rate unit is 1 kbps and the range is from 8k to 1048568k. The granularity of rate is 8 kbps.
* The ifg_include parameter is used for rate calculation with/without inter-frame-gap and preamble.
*/
extern rtk_api_ret_t rtk_rate_egrBandwidthCtrlRate_set(rtk_port_t port, rtk_rate_t rate, rtk_enable_t ifg_includ);
/* Function Name:
* rtk_rate_egrBandwidthCtrlRate_get
* Description:
* Get port egress bandwidth control
* Input:
* port - Port id
* Output:
* pRate - Rate of egress bandwidth
* pIfg_include - Rate's calculation including IFG, ENABLE:include DISABLE:exclude
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_PORT_ID - Invalid port number.
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The rate unit is 1 kbps and the range is from 8k to 1048568k. The granularity of rate is 8 kbps.
* The ifg_include parameter is used for rate calculation with/without inter-frame-gap and preamble.
*/
extern rtk_api_ret_t rtk_rate_egrBandwidthCtrlRate_get(rtk_port_t port, rtk_rate_t *pRate, rtk_enable_t *pIfg_include);
/* Function Name:
* rtk_rate_egrQueueBwCtrlEnable_set
* Description:
* Set enable status of egress bandwidth control on specified queue.
* Input:
* port - port id
* queue - queue id
* enable - enable status of egress queue bandwidth control
* Output:
* None
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_PORT_ID - invalid port id
* RT_ERR_QUEUE_ID - invalid queue id
* RT_ERR_INPUT - invalid input parameter
* Note:
* None
*/
extern rtk_api_ret_t rtk_rate_egrQueueBwCtrlEnable_set(rtk_port_t port, rtk_qid_t queue, rtk_enable_t enable);
/* Function Name:
* rtk_rate_egrQueueBwCtrlRate_get
* Description:
* Get rate of egress bandwidth control on specified queue.
* Input:
* port - port id
* queue - queue id
* pIndex - shared meter index
* Output:
* pRate - pointer to rate of egress queue bandwidth control
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_PORT_ID - invalid port id
* RT_ERR_QUEUE_ID - invalid queue id
* RT_ERR_FILTER_METER_ID - Invalid meter id
* Note:
* None.
*/
extern rtk_api_ret_t rtk_rate_egrQueueBwCtrlEnable_get(rtk_port_t port, rtk_qid_t queue, rtk_enable_t *pEnable);
/* Function Name:
* rtk_rate_egrQueueBwCtrlRate_set
* Description:
* Set rate of egress bandwidth control on specified queue.
* Input:
* port - port id
* queue - queue id
* index - shared meter index
* Output:
* None
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_PORT_ID - invalid port id
* RT_ERR_QUEUE_ID - invalid queue id
* RT_ERR_FILTER_METER_ID - Invalid meter id
* Note:
* The actual rate control is set in shared meters.
* The unit of granularity is 8Kbps.
*/
extern rtk_api_ret_t rtk_rate_egrQueueBwCtrlRate_set(rtk_port_t port, rtk_qid_t queue, rtk_meter_id_t index);
/* Function Name:
* rtk_rate_egrQueueBwCtrlRate_get
* Description:
* Get rate of egress bandwidth control on specified queue.
* Input:
* port - port id
* queue - queue id
* pIndex - shared meter index
* Output:
* pRate - pointer to rate of egress queue bandwidth control
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_PORT_ID - invalid port id
* RT_ERR_QUEUE_ID - invalid queue id
* RT_ERR_FILTER_METER_ID - Invalid meter id
* Note:
* The actual rate control is set in shared meters.
* The unit of granularity is 8Kbps.
*/
extern rtk_api_ret_t rtk_rate_egrQueueBwCtrlRate_get(rtk_port_t port, rtk_qid_t queue, rtk_meter_id_t *pIndex);
#endif /* __RTK_API_RATE_H__ */

View file

@ -0,0 +1,264 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* $Revision: 76306 $
* $Date: 2017-03-08 15:13:58 +0800 (g¤T, 08 ¤T¤ë 2017) $
*
* Purpose : Declaration of RLDP and RLPP API
*
* Feature : The file have include the following module and sub-modules
* 1) RLDP and RLPP configuration and status
*
*/
#ifndef __RTK_RLDP_H__
#define __RTK_RLDP_H__
/*
* Include Files
*/
/*
* Symbol Definition
*/
typedef enum rtk_rldp_trigger_e
{
RTK_RLDP_TRIGGER_SAMOVING = 0,
RTK_RLDP_TRIGGER_PERIOD,
RTK_RLDP_TRIGGER_END
} rtk_rldp_trigger_t;
typedef enum rtk_rldp_cmpType_e
{
RTK_RLDP_CMPTYPE_MAGIC = 0, /* Compare the RLDP with magic only */
RTK_RLDP_CMPTYPE_MAGIC_ID, /* Compare the RLDP with both magic + ID */
RTK_RLDP_CMPTYPE_END
} rtk_rldp_cmpType_t;
typedef enum rtk_rldp_loopStatus_e
{
RTK_RLDP_LOOPSTS_NONE = 0,
RTK_RLDP_LOOPSTS_LOOPING,
RTK_RLDP_LOOPSTS_END
} rtk_rldp_loopStatus_t;
typedef enum rtk_rlpp_trapType_e
{
RTK_RLPP_TRAPTYPE_NONE = 0,
RTK_RLPP_TRAPTYPE_CPU,
RTK_RLPP_TRAPTYPE_END
} rtk_rlpp_trapType_t;
typedef struct rtk_rldp_config_s
{
rtk_enable_t rldp_enable;
rtk_rldp_trigger_t trigger_mode;
rtk_mac_t magic;
rtk_rldp_cmpType_t compare_type;
rtk_uint32 interval_check; /* Checking interval for check state */
rtk_uint32 num_check; /* Checking number for check state */
rtk_uint32 interval_loop; /* Checking interval for loop state */
rtk_uint32 num_loop; /* Checking number for loop state */
} rtk_rldp_config_t;
typedef struct rtk_rldp_portConfig_s
{
rtk_enable_t tx_enable;
} rtk_rldp_portConfig_t;
typedef struct rtk_rldp_status_s
{
rtk_mac_t id;
} rtk_rldp_status_t;
typedef struct rtk_rldp_portStatus_s
{
rtk_rldp_loopStatus_t loop_status;
rtk_rldp_loopStatus_t loop_enter;
rtk_rldp_loopStatus_t loop_leave;
} rtk_rldp_portStatus_t;
/*
* Data Declaration
*/
/*
* Macro Declaration
*/
#define RTK_RLDP_INTERVAL_MAX 0xffff
#define RTK_RLDP_NUM_MAX 0xff
/*
* Function Declaration
*/
/* Module Name : RLDP */
/* Function Name:
* rtk_rldp_config_set
* Description:
* Set RLDP module configuration
* Input:
* pConfig - configuration structure of RLDP
* Output:
* None
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_INPUT
* RT_ERR_NULL_POINTER
* Note:
* None
*/
extern rtk_api_ret_t rtk_rldp_config_set(rtk_rldp_config_t *pConfig);
/* Function Name:
* rtk_rldp_config_get
* Description:
* Get RLDP module configuration
* Input:
* None
* Output:
* pConfig - configuration structure of RLDP
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_INPUT
* RT_ERR_NULL_POINTER
* Note:
* None
*/
extern rtk_api_ret_t rtk_rldp_config_get(rtk_rldp_config_t *pConfig);
/* Function Name:
* rtk_rldp_portConfig_set
* Description:
* Set per port RLDP module configuration
* Input:
* port - port number to be configured
* pPortConfig - per port configuration structure of RLDP
* Output:
* None
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_INPUT
* RT_ERR_NULL_POINTER
* Note:
* None
*/
extern rtk_api_ret_t rtk_rldp_portConfig_set(rtk_port_t port, rtk_rldp_portConfig_t *pPortConfig);
/* Function Name:
* rtk_rldp_portConfig_get
* Description:
* Get per port RLDP module configuration
* Input:
* port - port number to be get
* Output:
* pPortConfig - per port configuration structure of RLDP
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_INPUT
* RT_ERR_NULL_POINTER
* Note:
* None
*/
extern rtk_api_ret_t rtk_rldp_portConfig_get(rtk_port_t port, rtk_rldp_portConfig_t *pPortConfig);
/* Function Name:
* rtk_rldp_status_get
* Description:
* Get RLDP module status
* Input:
* None
* Output:
* pStatus - status structure of RLDP
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_NULL_POINTER
* Note:
* None
*/
extern rtk_api_ret_t rtk_rldp_status_get(rtk_rldp_status_t *pStatus);
/* Function Name:
* rtk_rldp_portStatus_get
* Description:
* Get RLDP module status
* Input:
* port - port number to be get
* Output:
* pPortStatus - per port status structure of RLDP
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_INPUT
* RT_ERR_NULL_POINTER
* Note:
* None
*/
extern rtk_api_ret_t rtk_rldp_portStatus_get(rtk_port_t port, rtk_rldp_portStatus_t *pPortStatus);
/* Function Name:
* rtk_rldp_portStatus_clear
* Description:
* Clear RLDP module status
* Input:
* port - port number to be clear
* pPortStatus - per port status structure of RLDP
* Output:
* None
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_INPUT
* RT_ERR_NULL_POINTER
* Note:
* Clear operation effect loop_enter and loop_leave only, other field in
* the structure are don't care
*/
extern rtk_api_ret_t rtk_rldp_portStatus_set(rtk_port_t port, rtk_rldp_portStatus_t *pPortStatus);
/* Function Name:
* rtk_rldp_portLoopPair_get
* Description:
* Get RLDP port loop pairs
* Input:
* port - port number to be get
* Output:
* pPortmask - per port related loop ports
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_INPUT
* RT_ERR_NULL_POINTER
* Note:
* None
*/
extern rtk_api_ret_t rtk_rldp_portLoopPair_get(rtk_port_t port, rtk_portmask_t *pPortmask);
#endif /* __RTK_RLDP_H__ */

View file

@ -0,0 +1,229 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* $Revision: 76306 $
* $Date: 2017-03-08 15:13:58 +0800 (, 08 2017) $
*
* Purpose : Definition the error number in the SDK.
* Feature : error definition
*
*/
#ifndef __COMMON_RT_ERROR_H__
#define __COMMON_RT_ERROR_H__
/*
* Include Files
*/
/*
* Data Type Declaration
*/
typedef enum rt_error_code_e
{
RT_ERR_FAILED = -1, /* General Error */
/* 0x0000xxxx for common error code */
RT_ERR_OK = 0, /* 0x00000000, OK */
RT_ERR_INPUT, /* 0x00000001, invalid input parameter */
RT_ERR_UNIT_ID, /* 0x00000002, invalid unit id */
RT_ERR_PORT_ID, /* 0x00000003, invalid port id */
RT_ERR_PORT_MASK, /* 0x00000004, invalid port mask */
RT_ERR_PORT_LINKDOWN, /* 0x00000005, link down port status */
RT_ERR_ENTRY_INDEX, /* 0x00000006, invalid entry index */
RT_ERR_NULL_POINTER, /* 0x00000007, input parameter is null pointer */
RT_ERR_QUEUE_ID, /* 0x00000008, invalid queue id */
RT_ERR_QUEUE_NUM, /* 0x00000009, invalid queue number */
RT_ERR_BUSYWAIT_TIMEOUT, /* 0x0000000a, busy watting time out */
RT_ERR_MAC, /* 0x0000000b, invalid mac address */
RT_ERR_OUT_OF_RANGE, /* 0x0000000c, input parameter out of range */
RT_ERR_CHIP_NOT_SUPPORTED, /* 0x0000000d, functions not supported by this chip model */
RT_ERR_SMI, /* 0x0000000e, SMI error */
RT_ERR_NOT_INIT, /* 0x0000000f, The module is not initial */
RT_ERR_CHIP_NOT_FOUND, /* 0x00000010, The chip can not found */
RT_ERR_NOT_ALLOWED, /* 0x00000011, actions not allowed by the function */
RT_ERR_DRIVER_NOT_FOUND, /* 0x00000012, The driver can not found */
RT_ERR_SEM_LOCK_FAILED, /* 0x00000013, Failed to lock semaphore */
RT_ERR_SEM_UNLOCK_FAILED, /* 0x00000014, Failed to unlock semaphore */
RT_ERR_ENABLE, /* 0x00000015, invalid enable parameter */
RT_ERR_TBL_FULL, /* 0x00000016, input table full */
/* 0x0001xxxx for vlan */
RT_ERR_VLAN_VID = 0x00010000, /* 0x00010000, invalid vid */
RT_ERR_VLAN_PRIORITY, /* 0x00010001, invalid 1p priority */
RT_ERR_VLAN_EMPTY_ENTRY, /* 0x00010002, emtpy entry of vlan table */
RT_ERR_VLAN_ACCEPT_FRAME_TYPE, /* 0x00010003, invalid accept frame type */
RT_ERR_VLAN_EXIST, /* 0x00010004, vlan is exist */
RT_ERR_VLAN_ENTRY_NOT_FOUND, /* 0x00010005, specified vlan entry not found */
RT_ERR_VLAN_PORT_MBR_EXIST, /* 0x00010006, member port exist in the specified vlan */
RT_ERR_VLAN_PROTO_AND_PORT, /* 0x00010008, invalid protocol and port based vlan */
/* 0x0002xxxx for svlan */
RT_ERR_SVLAN_ENTRY_INDEX = 0x00020000, /* 0x00020000, invalid svid entry no */
RT_ERR_SVLAN_ETHER_TYPE, /* 0x00020001, invalid SVLAN ether type */
RT_ERR_SVLAN_TABLE_FULL, /* 0x00020002, no empty entry in SVLAN table */
RT_ERR_SVLAN_ENTRY_NOT_FOUND, /* 0x00020003, specified svlan entry not found */
RT_ERR_SVLAN_EXIST, /* 0x00020004, SVLAN entry is exist */
RT_ERR_SVLAN_VID, /* 0x00020005, invalid svid */
/* 0x0003xxxx for MSTP */
RT_ERR_MSTI = 0x00030000, /* 0x00030000, invalid msti */
RT_ERR_MSTP_STATE, /* 0x00030001, invalid spanning tree status */
RT_ERR_MSTI_EXIST, /* 0x00030002, MSTI exist */
RT_ERR_MSTI_NOT_EXIST, /* 0x00030003, MSTI not exist */
/* 0x0004xxxx for BUCKET */
RT_ERR_TIMESLOT = 0x00040000, /* 0x00040000, invalid time slot */
RT_ERR_TOKEN, /* 0x00040001, invalid token amount */
RT_ERR_RATE, /* 0x00040002, invalid rate */
RT_ERR_TICK, /* 0x00040003, invalid tick */
/* 0x0005xxxx for RMA */
RT_ERR_RMA_ADDR = 0x00050000, /* 0x00050000, invalid rma mac address */
RT_ERR_RMA_ACTION, /* 0x00050001, invalid rma action */
/* 0x0006xxxx for L2 */
RT_ERR_L2_HASH_KEY = 0x00060000, /* 0x00060000, invalid L2 Hash key */
RT_ERR_L2_HASH_INDEX, /* 0x00060001, invalid L2 Hash index */
RT_ERR_L2_CAM_INDEX, /* 0x00060002, invalid L2 CAM index */
RT_ERR_L2_ENRTYSEL, /* 0x00060003, invalid EntrySel */
RT_ERR_L2_INDEXTABLE_INDEX, /* 0x00060004, invalid L2 index table(=portMask table) index */
RT_ERR_LIMITED_L2ENTRY_NUM, /* 0x00060005, invalid limited L2 entry number */
RT_ERR_L2_AGGREG_PORT, /* 0x00060006, this aggregated port is not the lowest physical
port of its aggregation group */
RT_ERR_L2_FID, /* 0x00060007, invalid fid */
RT_ERR_L2_VID, /* 0x00060008, invalid cvid */
RT_ERR_L2_NO_EMPTY_ENTRY, /* 0x00060009, no empty entry in L2 table */
RT_ERR_L2_ENTRY_NOTFOUND, /* 0x0006000a, specified entry not found */
RT_ERR_L2_INDEXTBL_FULL, /* 0x0006000b, the L2 index table is full */
RT_ERR_L2_INVALID_FLOWTYPE, /* 0x0006000c, invalid L2 flow type */
RT_ERR_L2_L2UNI_PARAM, /* 0x0006000d, invalid L2 unicast parameter */
RT_ERR_L2_L2MULTI_PARAM, /* 0x0006000e, invalid L2 multicast parameter */
RT_ERR_L2_IPMULTI_PARAM, /* 0x0006000f, invalid L2 ip multicast parameter */
RT_ERR_L2_PARTIAL_HASH_KEY, /* 0x00060010, invalid L2 partial Hash key */
RT_ERR_L2_EMPTY_ENTRY, /* 0x00060011, the entry is empty(invalid) */
RT_ERR_L2_FLUSH_TYPE, /* 0x00060012, the flush type is invalid */
RT_ERR_L2_NO_CPU_PORT, /* 0x00060013, CPU port not exist */
/* 0x0007xxxx for FILTER (PIE) */
RT_ERR_FILTER_BLOCKNUM = 0x00070000, /* 0x00070000, invalid block number */
RT_ERR_FILTER_ENTRYIDX, /* 0x00070001, invalid entry index */
RT_ERR_FILTER_CUTLINE, /* 0x00070002, invalid cutline value */
RT_ERR_FILTER_FLOWTBLBLOCK, /* 0x00070003, block belongs to flow table */
RT_ERR_FILTER_INACLBLOCK, /* 0x00070004, block belongs to ingress ACL */
RT_ERR_FILTER_ACTION, /* 0x00070005, action doesn't consist to entry type */
RT_ERR_FILTER_INACL_RULENUM, /* 0x00070006, invalid ACL rulenum */
RT_ERR_FILTER_INACL_TYPE, /* 0x00070007, entry type isn't an ingress ACL rule */
RT_ERR_FILTER_INACL_EXIST, /* 0x00070008, ACL entry is already exit */
RT_ERR_FILTER_INACL_EMPTY, /* 0x00070009, ACL entry is empty */
RT_ERR_FILTER_FLOWTBL_TYPE, /* 0x0007000a, entry type isn't an flow table rule */
RT_ERR_FILTER_FLOWTBL_RULENUM, /* 0x0007000b, invalid flow table rulenum */
RT_ERR_FILTER_FLOWTBL_EMPTY, /* 0x0007000c, flow table entry is empty */
RT_ERR_FILTER_FLOWTBL_EXIST, /* 0x0007000d, flow table entry is already exist */
RT_ERR_FILTER_METER_ID, /* 0x0007000e, invalid metering id */
RT_ERR_FILTER_LOG_ID, /* 0x0007000f, invalid log id */
RT_ERR_FILTER_INACL_NONE_BEGIN_IDX, /* 0x00070010, entry index is not starting index of a group of rules */
RT_ERR_FILTER_INACL_ACT_NOT_SUPPORT, /* 0x00070011, action not support */
RT_ERR_FILTER_INACL_RULE_NOT_SUPPORT, /* 0x00070012, rule not support */
/* 0x0008xxxx for ACL Rate Limit */
RT_ERR_ACLRL_HTHR = 0x00080000, /* 0x00080000, invalid high threshold */
RT_ERR_ACLRL_TIMESLOT, /* 0x00080001, invalid time slot */
RT_ERR_ACLRL_TOKEN, /* 0x00080002, invalid token amount */
RT_ERR_ACLRL_RATE, /* 0x00080003, invalid rate */
/* 0x0009xxxx for Link aggregation */
RT_ERR_LA_CPUPORT = 0x00090000, /* 0x00090000, CPU port can not be aggregated port */
RT_ERR_LA_TRUNK_ID, /* 0x00090001, invalid trunk id */
RT_ERR_LA_PORTMASK, /* 0x00090002, invalid port mask */
RT_ERR_LA_HASHMASK, /* 0x00090003, invalid hash mask */
RT_ERR_LA_DUMB, /* 0x00090004, this API should be used in 802.1ad dumb mode */
RT_ERR_LA_PORTNUM_DUMB, /* 0x00090005, it can only aggregate at most four ports when 802.1ad dumb mode */
RT_ERR_LA_PORTNUM_NORMAL, /* 0x00090006, it can only aggregate at most eight ports when 802.1ad normal mode */
RT_ERR_LA_MEMBER_OVERLAP, /* 0x00090007, the specified port mask is overlapped with other group */
RT_ERR_LA_NOT_MEMBER_PORT, /* 0x00090008, the port is not a member port of the trunk */
RT_ERR_LA_TRUNK_NOT_EXIST, /* 0x00090009, the trunk doesn't exist */
/* 0x000axxxx for storm filter */
RT_ERR_SFC_TICK_PERIOD = 0x000a0000, /* 0x000a0000, invalid SFC tick period */
RT_ERR_SFC_UNKNOWN_GROUP, /* 0x000a0001, Unknown Storm filter group */
/* 0x000bxxxx for pattern match */
RT_ERR_PM_MASK = 0x000b0000, /* 0x000b0000, invalid pattern length. Pattern length should be 8 */
RT_ERR_PM_LENGTH, /* 0x000b0001, invalid pattern match mask, first byte must care */
RT_ERR_PM_MODE, /* 0x000b0002, invalid pattern match mode */
/* 0x000cxxxx for input bandwidth control */
RT_ERR_INBW_TICK_PERIOD = 0x000c0000, /* 0x000c0000, invalid tick period for input bandwidth control */
RT_ERR_INBW_TOKEN_AMOUNT, /* 0x000c0001, invalid amount of token for input bandwidth control */
RT_ERR_INBW_FCON_VALUE, /* 0x000c0002, invalid flow control ON threshold value for input bandwidth control */
RT_ERR_INBW_FCOFF_VALUE, /* 0x000c0003, invalid flow control OFF threshold value for input bandwidth control */
RT_ERR_INBW_FC_ALLOWANCE, /* 0x000c0004, invalid allowance of incomming packet for input bandwidth control */
RT_ERR_INBW_RATE, /* 0x000c0005, invalid input bandwidth */
/* 0x000dxxxx for QoS */
RT_ERR_QOS_1P_PRIORITY = 0x000d0000, /* 0x000d0000, invalid 802.1P priority */
RT_ERR_QOS_DSCP_VALUE, /* 0x000d0001, invalid DSCP value */
RT_ERR_QOS_INT_PRIORITY, /* 0x000d0002, invalid internal priority */
RT_ERR_QOS_SEL_DSCP_PRI, /* 0x000d0003, invalid DSCP selection priority */
RT_ERR_QOS_SEL_PORT_PRI, /* 0x000d0004, invalid port selection priority */
RT_ERR_QOS_SEL_IN_ACL_PRI, /* 0x000d0005, invalid ingress ACL selection priority */
RT_ERR_QOS_SEL_CLASS_PRI, /* 0x000d0006, invalid classifier selection priority */
RT_ERR_QOS_EBW_RATE, /* 0x000d0007, invalid egress bandwidth rate */
RT_ERR_QOS_SCHE_TYPE, /* 0x000d0008, invalid QoS scheduling type */
RT_ERR_QOS_QUEUE_WEIGHT, /* 0x000d0009, invalid Queue weight */
RT_ERR_QOS_SEL_PRI_SOURCE, /* 0x000d000a, invalid selection of priority source */
/* 0x000exxxx for port ability */
RT_ERR_PHY_PAGE_ID = 0x000e0000, /* 0x000e0000, invalid PHY page id */
RT_ERR_PHY_REG_ID, /* 0x000e0001, invalid PHY reg id */
RT_ERR_PHY_DATAMASK, /* 0x000e0002, invalid PHY data mask */
RT_ERR_PHY_AUTO_NEGO_MODE, /* 0x000e0003, invalid PHY auto-negotiation mode*/
RT_ERR_PHY_SPEED, /* 0x000e0004, invalid PHY speed setting */
RT_ERR_PHY_DUPLEX, /* 0x000e0005, invalid PHY duplex setting */
RT_ERR_PHY_FORCE_ABILITY, /* 0x000e0006, invalid PHY force mode ability parameter */
RT_ERR_PHY_FORCE_1000, /* 0x000e0007, invalid PHY force mode 1G speed setting */
RT_ERR_PHY_TXRX, /* 0x000e0008, invalid PHY tx/rx */
RT_ERR_PHY_ID, /* 0x000e0009, invalid PHY id */
RT_ERR_PHY_RTCT_NOT_FINISH, /* 0x000e000a, PHY RTCT in progress */
/* 0x000fxxxx for mirror */
RT_ERR_MIRROR_DIRECTION = 0x000f0000, /* 0x000f0000, invalid error mirror direction */
RT_ERR_MIRROR_SESSION_FULL, /* 0x000f0001, mirroring session is full */
RT_ERR_MIRROR_SESSION_NOEXIST, /* 0x000f0002, mirroring session not exist */
RT_ERR_MIRROR_PORT_EXIST, /* 0x000f0003, mirroring port already exists */
RT_ERR_MIRROR_PORT_NOT_EXIST, /* 0x000f0004, mirroring port does not exists */
RT_ERR_MIRROR_PORT_FULL, /* 0x000f0005, Exceeds maximum number of supported mirroring port */
/* 0x0010xxxx for stat */
RT_ERR_STAT_INVALID_GLOBAL_CNTR = 0x00100000, /* 0x00100000, Invalid Global Counter */
RT_ERR_STAT_INVALID_PORT_CNTR, /* 0x00100001, Invalid Port Counter */
RT_ERR_STAT_GLOBAL_CNTR_FAIL, /* 0x00100002, Could not retrieve/reset Global Counter */
RT_ERR_STAT_PORT_CNTR_FAIL, /* 0x00100003, Could not retrieve/reset Port Counter */
RT_ERR_STAT_INVALID_CNTR, /* 0x00100004, Invalid Counter */
RT_ERR_STAT_CNTR_FAIL, /* 0x00100005, Could not retrieve/reset Counter */
/* 0x0011xxxx for dot1x */
RT_ERR_DOT1X_INVALID_DIRECTION = 0x00110000, /* 0x00110000, Invalid Authentication Direction */
RT_ERR_DOT1X_PORTBASEDPNEN, /* 0x00110001, Port-based enable port error */
RT_ERR_DOT1X_PORTBASEDAUTH, /* 0x00110002, Port-based auth port error */
RT_ERR_DOT1X_PORTBASEDOPDIR, /* 0x00110003, Port-based opdir error */
RT_ERR_DOT1X_MACBASEDPNEN, /* 0x00110004, MAC-based enable port error */
RT_ERR_DOT1X_MACBASEDOPDIR, /* 0x00110005, MAC-based opdir error */
RT_ERR_DOT1X_PROC, /* 0x00110006, unauthorized behavior error */
RT_ERR_DOT1X_GVLANIDX, /* 0x00110007, guest vlan index error */
RT_ERR_DOT1X_GVLANTALK, /* 0x00110008, guest vlan OPDIR error */
RT_ERR_DOT1X_MAC_PORT_MISMATCH, /* 0x00110009, Auth MAC and port mismatch eror */
RT_ERR_END /* The symbol is the latest symbol */
} rt_error_code_t;
#endif /* __COMMON_RT_ERROR_H__ */

View file

@ -0,0 +1,44 @@
#ifndef __RTK_HAL_H__
#define __RTK_HAL_H__
#include "ra_ioctl.h"
#define RTK_SW_VID_RANGE 16
void rtk_hal_switch_init(void);
void rtk_hal_dump_mib(void);
void rtk_hal_dump_full_mib(void);
int rtk_hal_dump_vlan(void);
void rtk_hal_clear_vlan(void);
int rtk_hal_set_vlan(struct ra_switch_ioctl_data *data);
int rtk_hal_set_ingress_rate(struct ra_switch_ioctl_data *data);
int rtk_hal_set_egress_rate(struct ra_switch_ioctl_data *data);
void rtk_hal_dump_table(void);
void rtk_hal_clear_table(void);
void rtk_hal_get_phy_status(struct ra_switch_ioctl_data *data);
void rtk_hal_set_port_mirror(struct ra_switch_ioctl_data *data);
void rtk_hal_read_reg(struct ra_switch_ioctl_data *data);
void rtk_hal_write_reg(struct ra_switch_ioctl_data *data);
void rtk_hal_qos_en(struct ra_switch_ioctl_data *data);
void rtk_hal_qos_set_table2type(struct ra_switch_ioctl_data *data);
void rtk_hal_qos_get_table2type(struct ra_switch_ioctl_data *data);
void rtk_hal_qos_set_port2table(struct ra_switch_ioctl_data *data);
void rtk_hal_qos_get_port2table(struct ra_switch_ioctl_data *data);
void rtk_hal_qos_set_port2pri(struct ra_switch_ioctl_data *data);
void rtk_hal_qos_get_port2pri(struct ra_switch_ioctl_data *data);
void rtk_hal_qos_set_dscp2pri(struct ra_switch_ioctl_data *data);
void rtk_hal_qos_get_dscp2pri(struct ra_switch_ioctl_data *data);
void rtk_hal_qos_set_pri2queue(struct ra_switch_ioctl_data *data);
void rtk_hal_qos_get_pri2queue(struct ra_switch_ioctl_data *data);
void rtk_hal_qos_set_queue_weight(struct ra_switch_ioctl_data *data);
void rtk_hal_qos_get_queue_weight(struct ra_switch_ioctl_data *data);
void rtk_hal_enable_igmpsnoop(struct ra_switch_ioctl_data *data);
void rtk_hal_disable_igmpsnoop(void);
void rtk_hal_set_phy_test_mode(struct ra_switch_ioctl_data *data);
void rtk_hal_get_phy_reg(struct ra_switch_ioctl_data *data);
void rtk_hal_set_phy_reg(struct ra_switch_ioctl_data *data);
void rtk_hal_vlan_tag(struct ra_switch_ioctl_data *data);
void rtk_hal_vlan_portpvid_set(rtk_port_t port, rtk_vlan_t pvid, rtk_pri_t priority);
void rtk_hal_add_table(struct ra_switch_ioctl_data *data);
void rtk_hal_del_table(struct ra_switch_ioctl_data *data);
void rtk_hal_vlan_mode(struct ra_switch_ioctl_data *data);
void rtk_hal_set_port_trunk(struct ra_switch_ioctl_data *data);
#endif

View file

@ -0,0 +1,737 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* $Revision: 76336 $
* $Date: 2017-03-09 10:41:21 +0800 (, 09 2017) $
*
* Purpose : RTK switch high-level API
* Feature : Here is a list of all functions and variables in this module.
*
*/
#ifndef __RTK_SWITCH_H__
#define __RTK_SWITCH_H__
#include <rtk_types.h>
#define UNDEFINE_PHY_PORT (0xFF)
#define RTK_SWITCH_PORT_NUM (32)
#define MAXPKTLEN_CFG_ID_MAX (1)
#define RTK_SWITCH_MAX_PKTLEN (0x3FFF)
typedef enum init_state_e
{
INIT_NOT_COMPLETED = 0,
INIT_COMPLETED,
INIT_STATE_END
} init_state_t;
typedef enum switch_chip_e
{
CHIP_RTL8367C = 0,
CHIP_RTL8370B,
CHIP_RTL8364B,
CHIP_RTL8363SC_VB,
CHIP_END
}switch_chip_t;
typedef enum port_type_e
{
UTP_PORT = 0,
EXT_PORT,
UNKNOWN_PORT = 0xFF,
PORT_TYPE_END
}port_type_t;
typedef struct rtk_switch_halCtrl_s
{
switch_chip_t switch_type;
rtk_uint32 l2p_port[RTK_SWITCH_PORT_NUM];
rtk_uint32 p2l_port[RTK_SWITCH_PORT_NUM];
port_type_t log_port_type[RTK_SWITCH_PORT_NUM];
rtk_uint32 ptp_port[RTK_SWITCH_PORT_NUM];
rtk_uint32 valid_portmask;
rtk_uint32 valid_utp_portmask;
rtk_uint32 valid_ext_portmask;
rtk_uint32 valid_cpu_portmask;
rtk_uint32 min_phy_port;
rtk_uint32 max_phy_port;
rtk_uint32 phy_portmask;
rtk_uint32 combo_logical_port;
rtk_uint32 hsg_logical_port;
rtk_uint32 sg_logical_portmask;
rtk_uint32 max_meter_id;
rtk_uint32 max_lut_addr_num;
rtk_uint32 trunk_group_mask;
}rtk_switch_halCtrl_t;
typedef enum rtk_switch_maxPktLen_linkSpeed_e {
MAXPKTLEN_LINK_SPEED_FE = 0,
MAXPKTLEN_LINK_SPEED_GE,
MAXPKTLEN_LINK_SPEED_END,
} rtk_switch_maxPktLen_linkSpeed_t;
/* UTIL MACRO */
#define RTK_CHK_INIT_STATE() \
do \
{ \
if(rtk_switch_initialState_get() != INIT_COMPLETED) \
{ \
return RT_ERR_NOT_INIT; \
} \
}while(0)
#define RTK_CHK_PORT_VALID(__port__) \
do \
{ \
if(rtk_switch_logicalPortCheck(__port__) != RT_ERR_OK) \
{ \
return RT_ERR_PORT_ID; \
} \
}while(0)
#define RTK_CHK_PORT_IS_UTP(__port__) \
do \
{ \
if(rtk_switch_isUtpPort(__port__) != RT_ERR_OK) \
{ \
return RT_ERR_PORT_ID; \
} \
}while(0)
#define RTK_CHK_PORT_IS_EXT(__port__) \
do \
{ \
if(rtk_switch_isExtPort(__port__) != RT_ERR_OK) \
{ \
return RT_ERR_PORT_ID; \
} \
}while(0)
#define RTK_CHK_PORT_IS_COMBO(__port__) \
do \
{ \
if(rtk_switch_isComboPort(__port__) != RT_ERR_OK) \
{ \
return RT_ERR_PORT_ID; \
} \
}while(0)
#define RTK_CHK_PORT_IS_PTP(__port__) \
do \
{ \
if(rtk_switch_isPtpPort(__port__) != RT_ERR_OK) \
{ \
return RT_ERR_PORT_ID; \
} \
}while(0)
#define RTK_CHK_PORTMASK_VALID(__portmask__) \
do \
{ \
if(rtk_switch_isPortMaskValid(__portmask__) != RT_ERR_OK) \
{ \
return RT_ERR_PORT_MASK; \
} \
}while(0)
#define RTK_CHK_PORTMASK_VALID_ONLY_UTP(__portmask__) \
do \
{ \
if(rtk_switch_isPortMaskUtp(__portmask__) != RT_ERR_OK) \
{ \
return RT_ERR_PORT_MASK; \
} \
}while(0)
#define RTK_CHK_PORTMASK_VALID_ONLY_EXT(__portmask__) \
do \
{ \
if(rtk_switch_isPortMaskExt(__portmask__) != RT_ERR_OK) \
{ \
return RT_ERR_PORT_MASK; \
} \
}while(0)
#define RTK_CHK_TRUNK_GROUP_VALID(__grpId__) \
do \
{ \
if(rtk_switch_isValidTrunkGrpId(__grpId__) != RT_ERR_OK) \
{ \
return RT_ERR_LA_TRUNK_ID; \
} \
}while(0)
#define RTK_PORTMASK_IS_PORT_SET(__portmask__, __port__) (((__portmask__).bits[0] & (0x00000001 << __port__)) ? 1 : 0)
#define RTK_PORTMASK_IS_EMPTY(__portmask__) (((__portmask__).bits[0] == 0) ? 1 : 0)
#define RTK_PORTMASK_CLEAR(__portmask__) ((__portmask__).bits[0] = 0)
#define RTK_PORTMASK_PORT_SET(__portmask__, __port__) ((__portmask__).bits[0] |= (0x00000001 << __port__))
#define RTK_PORTMASK_PORT_CLEAR(__portmask__, __port__) ((__portmask__).bits[0] &= ~(0x00000001 << __port__))
#define RTK_PORTMASK_ALLPORT_SET(__portmask__) (rtk_switch_logPortMask_get(&__portmask__))
#define RTK_PORTMASK_SCAN(__portmask__, __port__) for(__port__ = 0; __port__ < RTK_SWITCH_PORT_NUM; __port__++) if(RTK_PORTMASK_IS_PORT_SET(__portmask__, __port__))
#define RTK_PORTMASK_COMPARE(__portmask_A__, __portmask_B__) ((__portmask_A__).bits[0] - (__portmask_B__).bits[0])
#define RTK_SCAN_ALL_PHY_PORTMASK(__port__) for(__port__ = 0; __port__ < RTK_SWITCH_PORT_NUM; __port__++) if( (rtk_switch_phyPortMask_get() & (0x00000001 << __port__)))
#define RTK_SCAN_ALL_LOG_PORT(__port__) for(__port__ = 0; __port__ < RTK_SWITCH_PORT_NUM; __port__++) if( rtk_switch_logicalPortCheck(__port__) == RT_ERR_OK)
#define RTK_SCAN_ALL_LOG_PORTMASK(__portmask__) for((__portmask__).bits[0] = 0; (__portmask__).bits[0] < 0x7FFFF; (__portmask__).bits[0]++) if( rtk_switch_isPortMaskValid(&__portmask__) == RT_ERR_OK)
/* Port mask defination */
#define RTK_PHY_PORTMASK_ALL (rtk_switch_phyPortMask_get())
/* Port defination*/
#define RTK_MAX_LOGICAL_PORT_ID (rtk_switch_maxLogicalPort_get())
/* Function Name:
* rtk_switch_probe
* Description:
* Probe switch
* Input:
* None
* Output:
* None
* Return:
* RT_ERR_OK - Switch probed
* RT_ERR_FAILED - Switch Unprobed.
* Note:
*
*/
extern rtk_api_ret_t rtk_switch_probe(switch_chip_t *pSwitchChip);
/* Function Name:
* rtk_switch_initialState_set
* Description:
* Set initial status
* Input:
* state - Initial state;
* Output:
* None
* Return:
* RT_ERR_OK - Initialized
* RT_ERR_FAILED - Uninitialized
* Note:
*
*/
extern rtk_api_ret_t rtk_switch_initialState_set(init_state_t state);
/* Function Name:
* rtk_switch_initialState_get
* Description:
* Get initial status
* Input:
* None
* Output:
* None
* Return:
* INIT_COMPLETED - Initialized
* INIT_NOT_COMPLETED - Uninitialized
* Note:
*
*/
extern init_state_t rtk_switch_initialState_get(void);
/* Function Name:
* rtk_switch_logicalPortCheck
* Description:
* Check logical port ID.
* Input:
* logicalPort - logical port ID
* Output:
* None
* Return:
* RT_ERR_OK - Port ID is correct
* RT_ERR_FAILED - Port ID is not correct
* RT_ERR_NOT_INIT - Not Initialize
* Note:
*
*/
extern rtk_api_ret_t rtk_switch_logicalPortCheck(rtk_port_t logicalPort);
/* Function Name:
* rtk_switch_isUtpPort
* Description:
* Check is logical port a UTP port
* Input:
* logicalPort - logical port ID
* Output:
* None
* Return:
* RT_ERR_OK - Port ID is a UTP port
* RT_ERR_FAILED - Port ID is not a UTP port
* RT_ERR_NOT_INIT - Not Initialize
* Note:
*
*/
extern rtk_api_ret_t rtk_switch_isUtpPort(rtk_port_t logicalPort);
/* Function Name:
* rtk_switch_isExtPort
* Description:
* Check is logical port a Extension port
* Input:
* logicalPort - logical port ID
* Output:
* None
* Return:
* RT_ERR_OK - Port ID is a EXT port
* RT_ERR_FAILED - Port ID is not a EXT port
* RT_ERR_NOT_INIT - Not Initialize
* Note:
*
*/
extern rtk_api_ret_t rtk_switch_isExtPort(rtk_port_t logicalPort);
/* Function Name:
* rtk_switch_isHsgPort
* Description:
* Check is logical port a HSG port
* Input:
* logicalPort - logical port ID
* Output:
* None
* Return:
* RT_ERR_OK - Port ID is a HSG port
* RT_ERR_FAILED - Port ID is not a HSG port
* RT_ERR_NOT_INIT - Not Initialize
* Note:
*
*/
extern rtk_api_ret_t rtk_switch_isHsgPort(rtk_port_t logicalPort);
/* Function Name:
* rtk_switch_isSgmiiPort
* Description:
* Check is logical port a SGMII port
* Input:
* logicalPort - logical port ID
* Output:
* None
* Return:
* RT_ERR_OK - Port ID is a SGMII port
* RT_ERR_FAILED - Port ID is not a SGMII port
* RT_ERR_NOT_INIT - Not Initialize
* Note:
*
*/
extern rtk_api_ret_t rtk_switch_isSgmiiPort(rtk_port_t logicalPort);
/* Function Name:
* rtk_switch_isCPUPort
* Description:
* Check is logical port a CPU port
* Input:
* logicalPort - logical port ID
* Output:
* None
* Return:
* RT_ERR_OK - Port ID is a CPU port
* RT_ERR_FAILED - Port ID is not a CPU port
* RT_ERR_NOT_INIT - Not Initialize
* Note:
*
*/
extern rtk_api_ret_t rtk_switch_isCPUPort(rtk_port_t logicalPort);
/* Function Name:
* rtk_switch_isComboPort
* Description:
* Check is logical port a Combo port
* Input:
* logicalPort - logical port ID
* Output:
* None
* Return:
* RT_ERR_OK - Port ID is a combo port
* RT_ERR_FAILED - Port ID is not a combo port
* RT_ERR_NOT_INIT - Not Initialize
* Note:
*
*/
extern rtk_api_ret_t rtk_switch_isComboPort(rtk_port_t logicalPort);
/* Function Name:
* rtk_switch_ComboPort_get
* Description:
* Get Combo port ID
* Input:
* None
* Output:
* None
* Return:
* Port ID of combo port
* Note:
*
*/
extern rtk_uint32 rtk_switch_ComboPort_get(void);
/* Function Name:
* rtk_switch_isPtpPort
* Description:
* Check is logical port a PTP port
* Input:
* logicalPort - logical port ID
* Output:
* None
* Return:
* RT_ERR_OK - Port ID is a PTP port
* RT_ERR_FAILED - Port ID is not a PTP port
* RT_ERR_NOT_INIT - Not Initialize
* Note:
*
*/
extern rtk_api_ret_t rtk_switch_isPtpPort(rtk_port_t logicalPort);
/* Function Name:
* rtk_switch_port_L2P_get
* Description:
* Get physical port ID
* Input:
* logicalPort - logical port ID
* Output:
* None
* Return:
* Physical port ID
* Note:
*
*/
extern rtk_uint32 rtk_switch_port_L2P_get(rtk_port_t logicalPort);
/* Function Name:
* rtk_switch_port_P2L_get
* Description:
* Get logical port ID
* Input:
* physicalPort - physical port ID
* Output:
* None
* Return:
* logical port ID
* Note:
*
*/
extern rtk_port_t rtk_switch_port_P2L_get(rtk_uint32 physicalPort);
/* Function Name:
* rtk_switch_isPortMaskValid
* Description:
* Check portmask is valid or not
* Input:
* pPmask - logical port mask
* Output:
* None
* Return:
* RT_ERR_OK - port mask is valid
* RT_ERR_FAILED - port mask is not valid
* RT_ERR_NOT_INIT - Not Initialize
* RT_ERR_NULL_POINTER - Null pointer
* Note:
*
*/
extern rtk_api_ret_t rtk_switch_isPortMaskValid(rtk_portmask_t *pPmask);
/* Function Name:
* rtk_switch_isPortMaskUtp
* Description:
* Check all ports in portmask are only UTP port
* Input:
* pPmask - logical port mask
* Output:
* None
* Return:
* RT_ERR_OK - Only UTP port in port mask
* RT_ERR_FAILED - Not only UTP port in port mask
* RT_ERR_NOT_INIT - Not Initialize
* RT_ERR_NULL_POINTER - Null pointer
* Note:
*
*/
extern rtk_api_ret_t rtk_switch_isPortMaskUtp(rtk_portmask_t *pPmask);
/* Function Name:
* rtk_switch_isPortMaskExt
* Description:
* Check all ports in portmask are only EXT port
* Input:
* pPmask - logical port mask
* Output:
* None
* Return:
* RT_ERR_OK - Only EXT port in port mask
* RT_ERR_FAILED - Not only EXT port in port mask
* RT_ERR_NOT_INIT - Not Initialize
* RT_ERR_NULL_POINTER - Null pointer
* Note:
*
*/
extern rtk_api_ret_t rtk_switch_isPortMaskExt(rtk_portmask_t *pPmask);
/* Function Name:
* rtk_switch_portmask_L2P_get
* Description:
* Get physicl portmask from logical portmask
* Input:
* pLogicalPmask - logical port mask
* Output:
* pPhysicalPortmask - physical port mask
* Return:
* RT_ERR_OK - OK
* RT_ERR_NOT_INIT - Not Initialize
* RT_ERR_NULL_POINTER - Null pointer
* RT_ERR_PORT_MASK - Error port mask
* Note:
*
*/
extern rtk_api_ret_t rtk_switch_portmask_L2P_get(rtk_portmask_t *pLogicalPmask, rtk_uint32 *pPhysicalPortmask);
/* Function Name:
* rtk_switch_portmask_P2L_get
* Description:
* Get logical portmask from physical portmask
* Input:
* physicalPortmask - physical port mask
* Output:
* pLogicalPmask - logical port mask
* Return:
* RT_ERR_OK - OK
* RT_ERR_NOT_INIT - Not Initialize
* RT_ERR_NULL_POINTER - Null pointer
* RT_ERR_PORT_MASK - Error port mask
* Note:
*
*/
extern rtk_api_ret_t rtk_switch_portmask_P2L_get(rtk_uint32 physicalPortmask, rtk_portmask_t *pLogicalPmask);
/* Function Name:
* rtk_switch_phyPortMask_get
* Description:
* Get physical portmask
* Input:
* None
* Output:
* None
* Return:
* 0x00 - Not Initialize
* Other value - Physical port mask
* Note:
*
*/
rtk_uint32 rtk_switch_phyPortMask_get(void);
/* Function Name:
* rtk_switch_logPortMask_get
* Description:
* Get Logical portmask
* Input:
* None
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_NOT_INIT - Not Initialize
* RT_ERR_NULL_POINTER - Null pointer
* Note:
*
*/
rtk_api_ret_t rtk_switch_logPortMask_get(rtk_portmask_t *pPortmask);
/* Function Name:
* rtk_switch_init
* Description:
* Set chip to default configuration enviroment
* Input:
* None
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
* The API can set chip registers to default configuration for different release chip model.
*/
extern rtk_api_ret_t rtk_switch_init(void);
/* Function Name:
* rtk_switch_portMaxPktLen_set
* Description:
* Set Max packet length
* Input:
* port - Port ID
* speed - Speed
* cfgId - Configuration ID
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Error Input
* Note:
*/
extern rtk_api_ret_t rtk_switch_portMaxPktLen_set(rtk_port_t port, rtk_switch_maxPktLen_linkSpeed_t speed, rtk_uint32 cfgId);
/* Function Name:
* rtk_switch_portMaxPktLen_get
* Description:
* Get Max packet length
* Input:
* port - Port ID
* speed - Speed
* Output:
* pCfgId - Configuration ID
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Error Input
* Note:
*/
extern rtk_api_ret_t rtk_switch_portMaxPktLen_get(rtk_port_t port, rtk_switch_maxPktLen_linkSpeed_t speed, rtk_uint32 *pCfgId);
/* Function Name:
* rtk_switch_maxPktLenCfg_set
* Description:
* Set Max packet length configuration
* Input:
* cfgId - Configuration ID
* pktLen - Max packet length
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Error Input
* Note:
*/
extern rtk_api_ret_t rtk_switch_maxPktLenCfg_set(rtk_uint32 cfgId, rtk_uint32 pktLen);
/* Function Name:
* rtk_switch_maxPktLenCfg_get
* Description:
* Get Max packet length configuration
* Input:
* cfgId - Configuration ID
* pPktLen - Max packet length
* Output:
* None.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Error Input
* Note:
*/
extern rtk_api_ret_t rtk_switch_maxPktLenCfg_get(rtk_uint32 cfgId, rtk_uint32 *pPktLen);
/* Function Name:
* rtk_switch_greenEthernet_set
* Description:
* Set all Ports Green Ethernet state.
* Input:
* enable - Green Ethernet state.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_ENABLE - Invalid enable input.
* Note:
* This API can set all Ports Green Ethernet state.
* The configuration is as following:
* - DISABLE
* - ENABLE
*/
extern rtk_api_ret_t rtk_switch_greenEthernet_set(rtk_enable_t enable);
/* Function Name:
* rtk_switch_greenEthernet_get
* Description:
* Get all Ports Green Ethernet state.
* Input:
* None
* Output:
* pEnable - Green Ethernet state.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
* This API can get Green Ethernet state.
*/
extern rtk_api_ret_t rtk_switch_greenEthernet_get(rtk_enable_t *pEnable);
/* Function Name:
* rtk_switch_maxLogicalPort_get
* Description:
* Get Max logical port ID
* Input:
* None
* Output:
* None
* Return:
* Max logical port
* Note:
* This API can get max logical port
*/
extern rtk_port_t rtk_switch_maxLogicalPort_get(void);
/* Function Name:
* rtk_switch_maxMeterId_get
* Description:
* Get Max Meter ID
* Input:
* None
* Output:
* None
* Return:
* 0x00 - Not Initialize
* Other value - Max Meter ID
* Note:
*
*/
extern rtk_uint32 rtk_switch_maxMeterId_get(void);
/* Function Name:
* rtk_switch_maxLutAddrNumber_get
* Description:
* Get Max LUT Address number
* Input:
* None
* Output:
* None
* Return:
* 0x00 - Not Initialize
* Other value - Max LUT Address number
* Note:
*
*/
extern rtk_uint32 rtk_switch_maxLutAddrNumber_get(void);
/* Function Name:
* rtk_switch_isValidTrunkGrpId
* Description:
* Check if trunk group is valid or not
* Input:
* grpId - Group ID
* Output:
* None
* Return:
* RT_ERR_OK - Trunk Group ID is valid
* RT_ERR_LA_TRUNK_ID - Trunk Group ID is not valid
* Note:
*
*/
rtk_uint32 rtk_switch_isValidTrunkGrpId(rtk_uint32 grpId);
#endif

View file

@ -0,0 +1,155 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* $Revision: 76306 $
* $Date: 2017-03-08 15:13:58 +0800 (g¤T, 08 ¤T¤ë 2017) $
*
* Purpose : RTL8367C switch high-level type enum definition.
* Feature :
*
*/
#ifndef _RTL8367C_TYPES_H_
#define _RTL8367C_TYPES_H_
//#include <stdio.h>
typedef unsigned long long rtk_uint64;
typedef long long rtk_int64;
typedef unsigned int rtk_uint32;
typedef int rtk_int32;
typedef unsigned short rtk_uint16;
typedef short rtk_int16;
typedef unsigned char rtk_uint8;
typedef char rtk_int8;
#define CONST_T const
#define RTK_TOTAL_NUM_OF_WORD_FOR_1BIT_PORT_LIST 1
#define RTK_MAX_NUM_OF_PORT 8
#define RTK_PORT_ID_MAX (RTK_MAX_NUM_OF_PORT-1)
#define RTK_PHY_ID_MAX (RTK_MAX_NUM_OF_PORT-4)
#define RTK_MAX_PORT_MASK 0xFF
#define RTK_WHOLE_SYSTEM 0xFF
typedef struct rtk_portmask_s
{
rtk_uint32 bits[RTK_TOTAL_NUM_OF_WORD_FOR_1BIT_PORT_LIST];
} rtk_portmask_t;
typedef enum rtk_enable_e
{
DISABLED = 0,
ENABLED,
RTK_ENABLE_END
} rtk_enable_t;
#ifndef ETHER_ADDR_LEN
#define ETHER_ADDR_LEN 6
#endif
/* ethernet address type */
typedef struct rtk_mac_s
{
rtk_uint8 octet[ETHER_ADDR_LEN];
} rtk_mac_t;
typedef rtk_uint32 rtk_pri_t; /* priority vlaue */
typedef rtk_uint32 rtk_qid_t; /* queue id type */
typedef rtk_uint32 rtk_data_t;
typedef rtk_uint32 rtk_dscp_t; /* dscp vlaue */
typedef rtk_uint32 rtk_fid_t; /* filter id type */
typedef rtk_uint32 rtk_vlan_t; /* vlan id type */
typedef rtk_uint32 rtk_mac_cnt_t; /* MAC count type */
typedef rtk_uint32 rtk_meter_id_t; /* meter id type */
typedef rtk_uint32 rtk_rate_t; /* rate type */
typedef enum rtk_port_e
{
UTP_PORT0 = 0,
UTP_PORT1,
UTP_PORT2,
UTP_PORT3,
UTP_PORT4,
UTP_PORT5,
UTP_PORT6,
UTP_PORT7,
EXT_PORT0 = 16,
EXT_PORT1,
EXT_PORT2,
UNDEFINE_PORT = 30,
RTK_PORT_MAX = 31
} rtk_port_t;
#ifndef _RTL_TYPES_H
#if 0
typedef unsigned long long uint64;
typedef long long int64;
typedef unsigned int uint32;
typedef int int32;
typedef unsigned short uint16;
typedef short int16;
typedef unsigned char uint8;
typedef char int8;
#endif
typedef rtk_uint32 ipaddr_t;
typedef rtk_uint32 memaddr;
#ifndef ETHER_ADDR_LEN
#define ETHER_ADDR_LEN 6
#endif
typedef struct ether_addr_s {
rtk_uint8 octet[ETHER_ADDR_LEN];
} ether_addr_t;
#ifdef __KERNEL__
#define rtlglue_printf printk
#else
#define rtlglue_printf printf
#endif
#define PRINT rtlglue_printf
#endif /*_RTL_TYPES_H*/
/* type abstraction */
#ifdef EMBEDDED_SUPPORT
typedef rtk_int16 rtk_api_ret_t;
typedef rtk_int16 ret_t;
typedef rtk_uint32 rtk_u_long;
#else
typedef rtk_int32 rtk_api_ret_t;
typedef rtk_int32 ret_t;
typedef rtk_uint64 rtk_u_long_t;
#endif
#ifndef NULL
#define NULL 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#define CONST const
#endif /* _RTL8367C_TYPES_H_ */

View file

@ -0,0 +1,129 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* $Revision: 76306 $
* $Date: 2017-03-08 15:13:58 +0800 (g¤T, 08 ¤T¤ë 2017) $
*
* Purpose : RTL8367C switch high-level API for RTL8367C
* Feature :
*
*/
#ifndef _RTL8367C_ASICDRV_H_
#define _RTL8367C_ASICDRV_H_
#include <rtk_types.h>
#include <rtk_error.h>
#include <rtl8367c_reg.h>
#include <rtl8367c_base.h>
#define RTL8367C_REGBITLENGTH 16
#define RTL8367C_REGDATAMAX 0xFFFF
#define RTL8367C_VIDMAX 0xFFF
#define RTL8367C_EVIDMAX 0x1FFF
#define RTL8367C_CVIDXNO 32
#define RTL8367C_CVIDXMAX (RTL8367C_CVIDXNO-1)
#define RTL8367C_PRIMAX 7
#define RTL8367C_DSCPMAX 63
#define RTL8367C_PORTNO 11
#define RTL8367C_PORTIDMAX (RTL8367C_PORTNO-1)
#define RTL8367C_PMSKMAX ((1<<(RTL8367C_PORTNO))-1)
#define RTL8367C_PORTMASK 0x7FF
#define RTL8367C_PHYNO 5
#define RTL8367C_PHYIDMAX (RTL8367C_PHYNO-1)
#define RTL8367C_SVIDXNO 64
#define RTL8367C_SVIDXMAX (RTL8367C_SVIDXNO-1)
#define RTL8367C_MSTIMAX 15
#define RTL8367C_METERNO 64
#define RTL8367C_METERMAX (RTL8367C_METERNO-1)
#define RTL8367C_METERBUCKETSIZEMAX 0xFFFF
#define RTL8367C_QUEUENO 8
#define RTL8367C_QIDMAX (RTL8367C_QUEUENO-1)
#define RTL8367C_PHY_BUSY_CHECK_COUNTER 1000
#define RTL8367C_QOS_GRANULARTY_MAX 0x7FFFF
#define RTL8367C_QOS_GRANULARTY_LSB_MASK 0xFFFF
#define RTL8367C_QOS_GRANULARTY_LSB_OFFSET 0
#define RTL8367C_QOS_GRANULARTY_MSB_MASK 0x70000
#define RTL8367C_QOS_GRANULARTY_MSB_OFFSET 16
#define RTL8367C_QOS_GRANULARTY_UNIT_KBPS 8
#define RTL8367C_QOS_RATE_INPUT_MAX (0x1FFFF * 8)
#define RTL8367C_QOS_RATE_INPUT_MAX_HSG (0x7FFFF * 8)
#define RTL8367C_QOS_RATE_INPUT_MIN 8
#define RTL8367C_QOS_PPS_INPUT_MAX (0x7FFFF)
#define RTL8367C_QOS_PPS_INPUT_MIN 1
#define RTL8367C_QUEUE_MASK 0xFF
#define RTL8367C_EFIDMAX 0x7
#define RTL8367C_FIDMAX 0xF
#define RTL8367C_EAV_SECONDMAX 0xFFFFFFFF
#define RTL8367C_EAV_NANOSECONDMAX 0x3B9AC9FF
/* the above macro is generated by genDotH */
#define RTL8367C_VALID_REG_NO 3869
/*=======================================================================
* Enum
*========================================================================*/
enum RTL8367C_TABLE_ACCESS_OP
{
TB_OP_READ = 0,
TB_OP_WRITE
};
enum RTL8367C_TABLE_ACCESS_TARGET
{
TB_TARGET_ACLRULE = 1,
TB_TARGET_ACLACT,
TB_TARGET_CVLAN,
TB_TARGET_L2,
TB_TARGET_IGMP_GROUP
};
#define RTL8367C_TABLE_ACCESS_REG_DATA(op, target) ((op << 3) | target)
/*=======================================================================
* Structures
*========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
extern ret_t rtl8367c_setAsicRegBit(rtk_uint32 reg, rtk_uint32 bit, rtk_uint32 value);
extern ret_t rtl8367c_getAsicRegBit(rtk_uint32 reg, rtk_uint32 bit, rtk_uint32 *pValue);
extern ret_t rtl8367c_setAsicRegBits(rtk_uint32 reg, rtk_uint32 bits, rtk_uint32 value);
extern ret_t rtl8367c_getAsicRegBits(rtk_uint32 reg, rtk_uint32 bits, rtk_uint32 *pValue);
extern ret_t rtl8367c_setAsicReg(rtk_uint32 reg, rtk_uint32 value);
extern ret_t rtl8367c_getAsicReg(rtk_uint32 reg, rtk_uint32 *pValue);
#ifdef __cplusplus
}
#endif
#endif /*#ifndef _RTL8367C_ASICDRV_H_*/

View file

@ -0,0 +1,231 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* $Revision: 76306 $
* $Date: 2017-03-08 15:13:58 +0800 (śg¤T, 08 ¤T¤ë 2017) $
*
* Purpose : RTL8367C switch high-level API for RTL8367C
* Feature : ACL related function drivers
*
*/
#ifndef _RTL8367C_ASICDRV_ACL_H_
#define _RTL8367C_ASICDRV_ACL_H_
#include <rtl8367c_asicdrv.h>
#define RTL8367C_ACLRULENO 96
#define RTL8367C_ACLRULEMAX (RTL8367C_ACLRULENO-1)
#define RTL8367C_ACLRULEFIELDNO 8
#define RTL8367C_ACLTEMPLATENO 5
#define RTL8367C_ACLTYPEMAX (RTL8367C_ACLTEMPLATENO-1)
#define RTL8367C_ACLRULETBLEN 9
#define RTL8367C_ACLACTTBLEN 4
#define RTL8367C_ACLRULETBADDR(type, rule) ((type << 6) | rule)
#define RTL8367C_ACLRULETBADDR2(type, rule) ((type << 5) | (rule + 64))
#define ACL_ACT_CVLAN_ENABLE_MASK 0x1
#define ACL_ACT_SVLAN_ENABLE_MASK 0x2
#define ACL_ACT_PRIORITY_ENABLE_MASK 0x4
#define ACL_ACT_POLICING_ENABLE_MASK 0x8
#define ACL_ACT_FWD_ENABLE_MASK 0x10
#define ACL_ACT_INTGPIO_ENABLE_MASK 0x20
#define RTL8367C_ACLRULETAGBITS 5
#define RTL8367C_ACLRANGENO 16
#define RTL8367C_ACLRANGEMAX (RTL8367C_ACLRANGENO-1)
#define RTL8367C_ACL_PORTRANGEMAX (0xFFFF)
#define RTL8367C_ACL_ACT_TABLE_LEN (4)
enum ACLTCAMTYPES
{
CAREBITS= 0,
DATABITS
};
typedef enum aclFwdAct
{
RTL8367C_ACL_FWD_MIRROR = 0,
RTL8367C_ACL_FWD_REDIRECT,
RTL8367C_ACL_FWD_MIRRORFUNTION,
RTL8367C_ACL_FWD_TRAP,
} rtl8367c_aclFwd_t;
enum ACLFIELDTYPES
{
ACL_UNUSED,
ACL_DMAC0,
ACL_DMAC1,
ACL_DMAC2,
ACL_SMAC0,
ACL_SMAC1,
ACL_SMAC2,
ACL_ETHERTYPE,
ACL_STAG,
ACL_CTAG,
ACL_IP4SIP0 = 0x10,
ACL_IP4SIP1,
ACL_IP4DIP0,
ACL_IP4DIP1,
ACL_IP6SIP0WITHIPV4 = 0x20,
ACL_IP6SIP1WITHIPV4,
ACL_IP6DIP0WITHIPV4 = 0x28,
ACL_IP6DIP1WITHIPV4,
ACL_VIDRANGE = 0x30,
ACL_IPRANGE,
ACL_PORTRANGE,
ACL_FIELD_VALID,
ACL_FIELD_SELECT00 = 0x40,
ACL_FIELD_SELECT01,
ACL_FIELD_SELECT02,
ACL_FIELD_SELECT03,
ACL_FIELD_SELECT04,
ACL_FIELD_SELECT05,
ACL_FIELD_SELECT06,
ACL_FIELD_SELECT07,
ACL_FIELD_SELECT08,
ACL_FIELD_SELECT09,
ACL_FIELD_SELECT10,
ACL_FIELD_SELECT11,
ACL_FIELD_SELECT12,
ACL_FIELD_SELECT13,
ACL_FIELD_SELECT14,
ACL_FIELD_SELECT15,
ACL_TCPSPORT = 0x80,
ACL_TCPDPORT,
ACL_TCPFLAG,
ACL_UDPSPORT,
ACL_UDPDPORT,
ACL_ICMPCODETYPE,
ACL_IGMPTYPE,
ACL_SPORT,
ACL_DPORT,
ACL_IP4TOSPROTO,
ACL_IP4FLAGOFF,
ACL_TCNH,
ACL_CPUTAG,
ACL_L2PAYLOAD,
ACL_IP6SIP0,
ACL_IP6SIP1,
ACL_IP6SIP2,
ACL_IP6SIP3,
ACL_IP6SIP4,
ACL_IP6SIP5,
ACL_IP6SIP6,
ACL_IP6SIP7,
ACL_IP6DIP0,
ACL_IP6DIP1,
ACL_IP6DIP2,
ACL_IP6DIP3,
ACL_IP6DIP4,
ACL_IP6DIP5,
ACL_IP6DIP6,
ACL_IP6DIP7,
ACL_TYPE_END
};
struct acl_rule_smi_st{
rtk_uint16 rule_info;
rtk_uint16 field[RTL8367C_ACLRULEFIELDNO];
};
struct acl_rule_smi_ext_st{
rtk_uint16 rule_info;
};
typedef struct ACLRULESMI{
struct acl_rule_smi_st care_bits;
rtk_uint16 valid:1;
struct acl_rule_smi_st data_bits;
struct acl_rule_smi_ext_st care_bits_ext;
struct acl_rule_smi_ext_st data_bits_ext;
}rtl8367c_aclrulesmi;
struct acl_rule_st{
rtk_uint16 active_portmsk:11;
rtk_uint16 type:3;
rtk_uint16 tag_exist:5;
rtk_uint16 field[RTL8367C_ACLRULEFIELDNO];
};
typedef struct ACLRULE{
struct acl_rule_st data_bits;
rtk_uint16 valid:1;
struct acl_rule_st care_bits;
}rtl8367c_aclrule;
typedef struct rtl8367c_acltemplate_s{
rtk_uint8 field[8];
}rtl8367c_acltemplate_t;
typedef struct acl_act_s{
rtk_uint16 cvidx_cact:7;
rtk_uint16 cact:2;
rtk_uint16 svidx_sact:7;
rtk_uint16 sact:2;
rtk_uint16 aclmeteridx:7;
rtk_uint16 fwdpmask:11;
rtk_uint16 fwdact:2;
rtk_uint16 pridx:7;
rtk_uint16 priact:2;
rtk_uint16 gpio_pin:4;
rtk_uint16 gpio_en:1;
rtk_uint16 aclint:1;
rtk_uint16 cact_ext:2;
rtk_uint16 fwdact_ext:1;
rtk_uint16 tag_fmt:2;
}rtl8367c_acl_act_t;
typedef struct acl_rule_union_s
{
rtl8367c_aclrule aclRule;
rtl8367c_acl_act_t aclAct;
rtk_uint32 aclActCtrl;
rtk_uint32 aclNot;
}rtl8367c_acl_rule_union_t;
extern ret_t rtl8367c_setAsicAcl(rtk_uint32 port, rtk_uint32 enabled);
extern ret_t rtl8367c_getAsicAcl(rtk_uint32 port, rtk_uint32* pEnabled);
extern ret_t rtl8367c_setAsicAclUnmatchedPermit(rtk_uint32 port, rtk_uint32 enabled);
extern ret_t rtl8367c_getAsicAclUnmatchedPermit(rtk_uint32 port, rtk_uint32* pEnabled);
extern ret_t rtl8367c_setAsicAclRule(rtk_uint32 index, rtl8367c_aclrule *pAclRule);
extern ret_t rtl8367c_getAsicAclRule(rtk_uint32 index, rtl8367c_aclrule *pAclRule);
extern ret_t rtl8367c_setAsicAclNot(rtk_uint32 index, rtk_uint32 not);
extern ret_t rtl8367c_getAsicAclNot(rtk_uint32 index, rtk_uint32* pNot);
extern ret_t rtl8367c_setAsicAclTemplate(rtk_uint32 index, rtl8367c_acltemplate_t* pAclType);
extern ret_t rtl8367c_getAsicAclTemplate(rtk_uint32 index, rtl8367c_acltemplate_t *pAclType);
extern ret_t rtl8367c_setAsicAclAct(rtk_uint32 index, rtl8367c_acl_act_t* pAclAct);
extern ret_t rtl8367c_getAsicAclAct(rtk_uint32 index, rtl8367c_acl_act_t *pAclAct);
extern ret_t rtl8367c_setAsicAclActCtrl(rtk_uint32 index, rtk_uint32 aclActCtrl);
extern ret_t rtl8367c_getAsicAclActCtrl(rtk_uint32 index, rtk_uint32 *aclActCtrl);
extern ret_t rtl8367c_setAsicAclPortRange(rtk_uint32 index, rtk_uint32 type, rtk_uint32 upperPort, rtk_uint32 lowerPort);
extern ret_t rtl8367c_getAsicAclPortRange(rtk_uint32 index, rtk_uint32* pType, rtk_uint32* pUpperPort, rtk_uint32* pLowerPort);
extern ret_t rtl8367c_setAsicAclVidRange(rtk_uint32 index, rtk_uint32 type, rtk_uint32 upperVid, rtk_uint32 lowerVid);
extern ret_t rtl8367c_getAsicAclVidRange(rtk_uint32 index, rtk_uint32* pType, rtk_uint32* pUpperVid, rtk_uint32* pLowerVid);
extern ret_t rtl8367c_setAsicAclIpRange(rtk_uint32 index, rtk_uint32 type, ipaddr_t upperIp, ipaddr_t lowerIp);
extern ret_t rtl8367c_getAsicAclIpRange(rtk_uint32 index, rtk_uint32* pType, ipaddr_t* pUpperIp, ipaddr_t* pLowerIp);
extern ret_t rtl8367c_setAsicAclGpioPolarity(rtk_uint32 polarity);
extern ret_t rtl8367c_getAsicAclGpioPolarity(rtk_uint32* pPolarity);
#endif /*_RTL8367C_ASICDRV_ACL_H_*/

View file

@ -0,0 +1,49 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* $Revision: 76306 $
* $Date: 2017-03-08 15:13:58 +0800 (g¤T, 08 ¤T¤ë 2017) $
*
* Purpose : RTL8367C switch high-level API for RTL8367C
* Feature : Proprietary CPU-tag related function drivers
*
*/
#ifndef _RTL8367C_ASICDRV_CPUTAG_H_
#define _RTL8367C_ASICDRV_CPUTAG_H_
#include <rtl8367c_asicdrv.h>
enum CPUTAG_INSERT_MODE
{
CPUTAG_INSERT_TO_ALL = 0,
CPUTAG_INSERT_TO_TRAPPING,
CPUTAG_INSERT_TO_NO,
CPUTAG_INSERT_END
};
extern ret_t rtl8367c_setAsicCputagEnable(rtk_uint32 enabled);
extern ret_t rtl8367c_getAsicCputagEnable(rtk_uint32 *pEnabled);
extern ret_t rtl8367c_setAsicCputagTrapPort(rtk_uint32 port);
extern ret_t rtl8367c_getAsicCputagTrapPort(rtk_uint32 *pPort);
extern ret_t rtl8367c_setAsicCputagPortmask(rtk_uint32 portmask);
extern ret_t rtl8367c_getAsicCputagPortmask(rtk_uint32 *pPmsk);
extern ret_t rtl8367c_setAsicCputagInsertMode(rtk_uint32 mode);
extern ret_t rtl8367c_getAsicCputagInsertMode(rtk_uint32 *pMode);
extern ret_t rtl8367c_setAsicCputagPriorityRemapping(rtk_uint32 srcPri, rtk_uint32 newPri);
extern ret_t rtl8367c_getAsicCputagPriorityRemapping(rtk_uint32 srcPri, rtk_uint32 *pNewPri);
extern ret_t rtl8367c_setAsicCputagPosition(rtk_uint32 postion);
extern ret_t rtl8367c_getAsicCputagPosition(rtk_uint32* pPostion);
extern ret_t rtl8367c_setAsicCputagMode(rtk_uint32 mode);
extern ret_t rtl8367c_getAsicCputagMode(rtk_uint32 *pMode);
extern ret_t rtl8367c_setAsicCputagRxMinLength(rtk_uint32 mode);
extern ret_t rtl8367c_getAsicCputagRxMinLength(rtk_uint32 *pMode);
#endif /*#ifndef _RTL8367C_ASICDRV_CPUTAG_H_*/

View file

@ -0,0 +1,52 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* $Revision: 76306 $
* $Date: 2017-03-08 15:13:58 +0800 (g¤T, 08 ¤T¤ë 2017) $
*
* Purpose : RTL8367C switch high-level API for RTL8367C
* Feature : 802.1X related functions
*
*/
#ifndef _RTL8367C_ASICDRV_DOT1X_H_
#define _RTL8367C_ASICDRV_DOT1X_H_
#include <rtl8367c_asicdrv.h>
enum DOT1X_UNAUTH_BEHAV
{
DOT1X_UNAUTH_DROP = 0,
DOT1X_UNAUTH_TRAP,
DOT1X_UNAUTH_GVLAN,
DOT1X_UNAUTH_END
};
extern ret_t rtl8367c_setAsic1xPBEnConfig(rtk_uint32 port, rtk_uint32 enabled);
extern ret_t rtl8367c_getAsic1xPBEnConfig(rtk_uint32 port, rtk_uint32 *pEnabled);
extern ret_t rtl8367c_setAsic1xPBAuthConfig(rtk_uint32 port, rtk_uint32 auth);
extern ret_t rtl8367c_getAsic1xPBAuthConfig(rtk_uint32 port, rtk_uint32 *pAuth);
extern ret_t rtl8367c_setAsic1xPBOpdirConfig(rtk_uint32 port, rtk_uint32 opdir);
extern ret_t rtl8367c_getAsic1xPBOpdirConfig(rtk_uint32 port, rtk_uint32 *pOpdir);
extern ret_t rtl8367c_setAsic1xMBEnConfig(rtk_uint32 port, rtk_uint32 enabled);
extern ret_t rtl8367c_getAsic1xMBEnConfig(rtk_uint32 port, rtk_uint32 *pEnabled);
extern ret_t rtl8367c_setAsic1xMBOpdirConfig(rtk_uint32 opdir);
extern ret_t rtl8367c_getAsic1xMBOpdirConfig(rtk_uint32 *pOpdir);
extern ret_t rtl8367c_setAsic1xProcConfig(rtk_uint32 port, rtk_uint32 proc);
extern ret_t rtl8367c_getAsic1xProcConfig(rtk_uint32 port, rtk_uint32 *pProc);
extern ret_t rtl8367c_setAsic1xGuestVidx(rtk_uint32 index);
extern ret_t rtl8367c_getAsic1xGuestVidx(rtk_uint32 *pIndex);
extern ret_t rtl8367c_setAsic1xGVOpdir(rtk_uint32 enabled);
extern ret_t rtl8367c_getAsic1xGVOpdir(rtk_uint32 *pEnabled);
extern ret_t rtl8367c_setAsic1xTrapPriority(rtk_uint32 priority);
extern ret_t rtl8367c_getAsic1xTrapPriority(rtk_uint32 *pPriority);
#endif /*_RTL8367C_ASICDRV_DOT1X_H_*/

View file

@ -0,0 +1,109 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* $Revision: 76306 $
* $Date: 2017-03-08 15:13:58 +0800 (g¤T, 08 ¤T¤ë 2017) $
*
* Purpose : RTL8367C switch high-level API for RTL8367C
* Feature : Ethernet AV related functions
*
*/
#ifndef _RTL8367C_ASICDRV_EAV_H_
#define _RTL8367C_ASICDRV_EAV_H_
#include <rtl8367c_asicdrv.h>
typedef enum RTL8367C_PTP_TIME_CMD_E
{
PTP_TIME_READ = 0,
PTP_TIME_WRITE,
PTP_TIME_INC,
PTP_TIME_DEC,
PTP_TIME_CMD_END
}RTL8367C_PTP_TIME_CMD;
typedef enum RTL8367C_PTP_TIME_ADJ_E
{
PTP_TIME_ADJ_INC = 0,
PTP_TIME_ADJ_DEC,
PTP_TIME_ADJ_END
}RTL8367C_PTP_TIME_ADJ;
typedef enum RTL8367C_PTP_TIME_CTRL_E
{
PTP_TIME_CTRL_STOP = 0,
PTP_TIME_CTRL_START,
PTP_TIME_CTRL_END
}RTL8367C_PTP_TIME_CTRL;
typedef enum RTL8367C_PTP_INTR_IMRS_E
{
PTP_IMRS_TX_SYNC,
PTP_IMRS_TX_DELAY_REQ,
PTP_IMRS_TX_PDELAY_REQ,
PTP_IMRS_TX_PDELAY_RESP,
PTP_IMRS_RX_SYNC,
PTP_IMRS_RX_DELAY_REQ,
PTP_IMRS_RX_PDELAY_REQ,
PTP_IMRS_RX_PDELAY_RESP,
PTP_IMRS_END,
}RTL8367C_PTP_INTR_IMRS;
typedef enum RTL8367C_PTP_PKT_TYPE_E
{
PTP_PKT_TYPE_TX_SYNC,
PTP_PKT_TYPE_TX_DELAY_REQ,
PTP_PKT_TYPE_TX_PDELAY_REQ,
PTP_PKT_TYPE_TX_PDELAY_RESP,
PTP_PKT_TYPE_RX_SYNC,
PTP_PKT_TYPE_RX_DELAY_REQ,
PTP_PKT_TYPE_RX_PDELAY_REQ,
PTP_PKT_TYPE_RX_PDELAY_RESP,
PTP_PKT_TYPE_END,
}RTL8367C_PTP_PKT_TYPE;
typedef struct rtl8367c_ptp_time_stamp_s{
rtk_uint32 sequence_id;
rtk_uint32 second;
rtk_uint32 nano_second;
}rtl8367c_ptp_time_stamp_t;
#define RTL8367C_PTP_INTR_MASK 0xFF
#define RTL8367C_PTP_PORT_MASK 0x3FF
extern ret_t rtl8367c_setAsicEavMacAddress(ether_addr_t mac);
extern ret_t rtl8367c_getAsicEavMacAddress(ether_addr_t *pMac);
extern ret_t rtl8367c_setAsicEavTpid(rtk_uint32 outerTag, rtk_uint32 innerTag);
extern ret_t rtl8367c_getAsicEavTpid(rtk_uint32* pOuterTag, rtk_uint32* pInnerTag);
extern ret_t rtl8367c_setAsicEavSysTime(rtk_uint32 second, rtk_uint32 nanoSecond);
extern ret_t rtl8367c_getAsicEavSysTime(rtk_uint32* pSecond, rtk_uint32* pNanoSecond);
extern ret_t rtl8367c_setAsicEavSysTimeAdjust(rtk_uint32 type, rtk_uint32 second, rtk_uint32 nanoSecond);
extern ret_t rtl8367c_setAsicEavSysTimeCtrl(rtk_uint32 control);
extern ret_t rtl8367c_getAsicEavSysTimeCtrl(rtk_uint32* pControl);
extern ret_t rtl8367c_setAsicEavInterruptMask(rtk_uint32 imr);
extern ret_t rtl8367c_getAsicEavInterruptMask(rtk_uint32* pImr);
extern ret_t rtl8367c_getAsicEavInterruptStatus(rtk_uint32* pIms);
extern ret_t rtl8367c_setAsicEavPortInterruptStatus(rtk_uint32 port, rtk_uint32 ims);
extern ret_t rtl8367c_getAsicEavPortInterruptStatus(rtk_uint32 port, rtk_uint32* pIms);
extern ret_t rtl8367c_setAsicEavPortEnable(rtk_uint32 port, rtk_uint32 enabled);
extern ret_t rtl8367c_getAsicEavPortEnable(rtk_uint32 port, rtk_uint32 *pEnabled);
extern ret_t rtl8367c_getAsicEavPortTimeStamp(rtk_uint32 port, rtk_uint32 type, rtl8367c_ptp_time_stamp_t* timeStamp);
extern ret_t rtl8367c_setAsicEavTrap(rtk_uint32 port, rtk_uint32 enabled);
extern ret_t rtl8367c_getAsicEavTrap(rtk_uint32 port, rtk_uint32 *pEnabled);
extern ret_t rtl8367c_setAsicEavEnable(rtk_uint32 port, rtk_uint32 enabled);
extern ret_t rtl8367c_getAsicEavEnable(rtk_uint32 port, rtk_uint32 *pEnabled);
extern ret_t rtl8367c_setAsicEavPriRemapping(rtk_uint32 srcpriority, rtk_uint32 priority);
extern ret_t rtl8367c_getAsicEavPriRemapping(rtk_uint32 srcpriority, rtk_uint32 *pPriority);
#endif /*#ifndef _RTL8367C_ASICDRV_EAV_H_*/

View file

@ -0,0 +1,31 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* $Revision: 48989 $
* $Date: 2014-07-01 15:45:24 +0800 (g¤G, 01 ¤C¤ë 2014) $
*
* Purpose : RTL8370 switch high-level API for RTL8367C
* Feature :
*
*/
#ifndef _RTL8367C_ASICDRV_EEE_H_
#define _RTL8367C_ASICDRV_EEE_H_
#include <rtl8367c_asicdrv.h>
#define EEE_OCP_PHY_ADDR (0xA5D0)
extern ret_t rtl8367c_setAsicEee100M(rtk_uint32 port, rtk_uint32 enable);
extern ret_t rtl8367c_getAsicEee100M(rtk_uint32 port, rtk_uint32 *enable);
extern ret_t rtl8367c_setAsicEeeGiga(rtk_uint32 port, rtk_uint32 enable);
extern ret_t rtl8367c_getAsicEeeGiga(rtk_uint32 port, rtk_uint32 *enable);
#endif /*_RTL8367C_ASICDRV_EEE_H_*/

View file

@ -0,0 +1,99 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* $Revision: 76306 $
* $Date: 2017-03-08 15:13:58 +0800 (g¤T, 08 ¤T¤ë 2017) $
*
* Purpose : RTL8367C switch high-level API for RTL8367C
* Feature : Flow control related functions
*
*/
#ifndef _RTL8367C_ASICDRV_FC_H_
#define _RTL8367C_ASICDRV_FC_H_
#include <rtl8367c_asicdrv.h>
#define RTL8367C_PAGE_NUMBER 0x600
enum FLOW_CONTROL_TYPE
{
FC_EGRESS = 0,
FC_INGRESS,
};
enum FC_JUMBO_SIZE
{
FC_JUMBO_SIZE_3K = 0,
FC_JUMBO_SIZE_4K,
FC_JUMBO_SIZE_6K,
FC_JUMBO_SIZE_9K,
FC_JUMBO_SIZE_END,
};
extern ret_t rtl8367c_setAsicFlowControlSelect(rtk_uint32 select);
extern ret_t rtl8367c_getAsicFlowControlSelect(rtk_uint32 *pSelect);
extern ret_t rtl8367c_setAsicFlowControlJumboMode(rtk_uint32 enabled);
extern ret_t rtl8367c_getAsicFlowControlJumboMode(rtk_uint32* pEnabled);
extern ret_t rtl8367c_setAsicFlowControlJumboModeSize(rtk_uint32 size);
extern ret_t rtl8367c_getAsicFlowControlJumboModeSize(rtk_uint32* pSize);
extern ret_t rtl8367c_setAsicFlowControlQueueEgressEnable(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 enabled);
extern ret_t rtl8367c_getAsicFlowControlQueueEgressEnable(rtk_uint32 port, rtk_uint32 qid, rtk_uint32* pEnabled);
extern ret_t rtl8367c_setAsicFlowControlDropAll(rtk_uint32 dropall);
extern ret_t rtl8367c_getAsicFlowControlDropAll(rtk_uint32* pDropall);
extern ret_t rtl8367c_setAsicFlowControlPauseAllThreshold(rtk_uint32 threshold);
extern ret_t rtl8367c_getAsicFlowControlPauseAllThreshold(rtk_uint32 *pThreshold);
extern ret_t rtl8367c_setAsicFlowControlSystemThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold);
extern ret_t rtl8367c_getAsicFlowControlSystemThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold);
extern ret_t rtl8367c_setAsicFlowControlSharedThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold);
extern ret_t rtl8367c_getAsicFlowControlSharedThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold);
extern ret_t rtl8367c_setAsicFlowControlPortThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold);
extern ret_t rtl8367c_getAsicFlowControlPortThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold);
extern ret_t rtl8367c_setAsicFlowControlPortPrivateThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold);
extern ret_t rtl8367c_getAsicFlowControlPortPrivateThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold);
extern ret_t rtl8367c_setAsicFlowControlSystemDropThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold);
extern ret_t rtl8367c_getAsicFlowControlSystemDropThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold);
extern ret_t rtl8367c_setAsicFlowControlSharedDropThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold);
extern ret_t rtl8367c_getAsicFlowControlSharedDropThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold);
extern ret_t rtl8367c_setAsicFlowControlPortDropThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold);
extern ret_t rtl8367c_getAsicFlowControlPortDropThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold);
extern ret_t rtl8367c_setAsicFlowControlPortPrivateDropThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold);
extern ret_t rtl8367c_getAsicFlowControlPortPrivateDropThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold);
extern ret_t rtl8367c_setAsicFlowControlSystemJumboThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold);
extern ret_t rtl8367c_getAsicFlowControlSystemJumboThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold);
extern ret_t rtl8367c_setAsicFlowControlSharedJumboThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold);
extern ret_t rtl8367c_getAsicFlowControlSharedJumboThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold);
extern ret_t rtl8367c_setAsicFlowControlPortJumboThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold);
extern ret_t rtl8367c_getAsicFlowControlPortJumboThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold);
extern ret_t rtl8367c_setAsicFlowControlPortPrivateJumboThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold);
extern ret_t rtl8367c_getAsicFlowControlPortPrivateJumboThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold);
extern ret_t rtl8367c_setAsicEgressFlowControlPortDropGap(rtk_uint32 gap);
extern ret_t rtl8367c_getAsicEgressFlowControlPortDropGap(rtk_uint32 *pGap);
extern ret_t rtl8367c_setAsicEgressFlowControlQueueDropGap(rtk_uint32 gap);
extern ret_t rtl8367c_getAsicEgressFlowControlQueueDropGap(rtk_uint32 *pGap);
extern ret_t rtl8367c_setAsicEgressFlowControlPortDropThreshold(rtk_uint32 port, rtk_uint32 threshold);
extern ret_t rtl8367c_getAsicEgressFlowControlPortDropThreshold(rtk_uint32 port, rtk_uint32 *pThreshold);
extern ret_t rtl8367c_setAsicEgressFlowControlQueueDropThreshold(rtk_uint32 qid, rtk_uint32 threshold);
extern ret_t rtl8367c_getAsicEgressFlowControlQueueDropThreshold(rtk_uint32 qid, rtk_uint32 *pThreshold);
extern ret_t rtl8367c_getAsicEgressQueueEmptyPortMask(rtk_uint32 *pPortmask);
extern ret_t rtl8367c_getAsicTotalPage(rtk_uint32 *pPageCount);
extern ret_t rtl8367c_getAsicPulbicPage(rtk_uint32 *pPageCount);
extern ret_t rtl8367c_getAsicMaxTotalPage(rtk_uint32 *pPageCount);
extern ret_t rtl8367c_getAsicMaxPulbicPage(rtk_uint32 *pPageCount);
extern ret_t rtl8367c_getAsicPortPage(rtk_uint32 port, rtk_uint32 *pPageCount);
extern ret_t rtl8367c_getAsicPortPageMax(rtk_uint32 port, rtk_uint32 *pPageCount);
extern ret_t rtl8367c_setAsicFlowControlEgressPortIndep(rtk_uint32 port, rtk_uint32 enable);
extern ret_t rtl8367c_getAsicFlowControlEgressPortIndep(rtk_uint32 port, rtk_uint32 *pEnable);
#endif /*_RTL8367C_ASICDRV_FC_H_*/

View file

@ -0,0 +1,36 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* $Revision: 76306 $
* $Date: 2017-03-08 15:13:58 +0800 (g¤T, 08 ¤T¤ë 2017) $
*
* Purpose : RTL8367C switch high-level API for RTL8367C
* Feature : Green ethernet related functions
*
*/
#ifndef _RTL8367C_ASICDRV_GREEN_H_
#define _RTL8367C_ASICDRV_GREEN_H_
#include <rtl8367c_asicdrv.h>
#include <rtl8367c_asicdrv_phy.h>
#define PHY_POWERSAVING_REG 24
extern ret_t rtl8367c_setAsicGreenTrafficType(rtk_uint32 priority, rtk_uint32 traffictype);
extern ret_t rtl8367c_getAsicGreenTrafficType(rtk_uint32 priority, rtk_uint32* pTraffictype);
extern ret_t rtl8367c_getAsicGreenPortPage(rtk_uint32 port, rtk_uint32* pPage);
extern ret_t rtl8367c_getAsicGreenHighPriorityTraffic(rtk_uint32 port, rtk_uint32* pIndicator);
extern ret_t rtl8367c_setAsicGreenHighPriorityTraffic(rtk_uint32 port);
extern ret_t rtl8367c_setAsicGreenEthernet(rtk_uint32 port, rtk_uint32 green);
extern ret_t rtl8367c_getAsicGreenEthernet(rtk_uint32 port, rtk_uint32* green);
extern ret_t rtl8367c_setAsicPowerSaving(rtk_uint32 phy, rtk_uint32 enable);
extern ret_t rtl8367c_getAsicPowerSaving(rtk_uint32 phy, rtk_uint32* enable);
#endif /*#ifndef _RTL8367C_ASICDRV_GREEN_H_*/

View file

@ -0,0 +1,43 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* $Revision: 76306 $
* $Date: 2017-03-08 15:13:58 +0800 (g¤T, 08 ¤T¤ë 2017) $
*
* Purpose : RTL8367C switch high-level API for RTL8367C
* Feature : Field selector related functions
*
*/
#ifndef _RTL8367C_ASICDRV__HSB_H_
#define _RTL8367C_ASICDRV__HSB_H_
#include <rtl8367c_asicdrv.h>
#define RTL8367C_FIELDSEL_FORMAT_NUMBER (16)
#define RTL8367C_FIELDSEL_MAX_OFFSET (255)
enum FIELDSEL_FORMAT_FORMAT
{
FIELDSEL_FORMAT_DEFAULT = 0,
FIELDSEL_FORMAT_RAW,
FIELDSEL_FORMAT_LLC,
FIELDSEL_FORMAT_IPV4,
FIELDSEL_FORMAT_ARP,
FIELDSEL_FORMAT_IPV6,
FIELDSEL_FORMAT_IPPAYLOAD,
FIELDSEL_FORMAT_L4PAYLOAD,
FIELDSEL_FORMAT_END
};
extern ret_t rtl8367c_setAsicFieldSelector(rtk_uint32 index, rtk_uint32 format, rtk_uint32 offset);
extern ret_t rtl8367c_getAsicFieldSelector(rtk_uint32 index, rtk_uint32* pFormat, rtk_uint32* pOffset);
#endif /*_RTL8367C_ASICDRV__HSB_H_*/

View file

@ -0,0 +1,47 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* $Revision: 38651 $
* $Date: 2016-02-27 14:32:56 +0800 (©P¤T, 17 ¥|¤ë 2016) $
*
* Purpose : RTL8367C switch high-level API for RTL8367C
* Feature : I2C related functions
*
*/
#ifndef _RTL8367C_ASICDRV_I2C_H_
#define _RTL8367C_ASICDRV_I2C_H_
#include <rtk_types.h>
#include <rtl8367c_asicdrv.h>
#define TIMEROUT_FOR_MICROSEMI (0x400)
#define GPIO_INPUT 1
#define GPIO_OUTPUT 2
extern ret_t rtl8367c_setAsicI2C_checkBusIdle(void);
extern ret_t rtl8367c_setAsicI2CStartCmd(void);
extern ret_t rtl8367c_setAsicI2CStopCmd(void);
extern ret_t rtl8367c_setAsicI2CTxOneCharCmd(rtk_uint8 oneChar);
extern ret_t rtl8367c_setAsicI2CcheckRxAck(void);
extern ret_t rtl8367c_setAsicI2CRxOneCharCmd(rtk_uint8 *pValue);
extern ret_t rtl8367c_setAsicI2CTxAckCmd(void);
extern ret_t rtl8367c_setAsicI2CTxNoAckCmd(void);
extern ret_t rtl8367c_setAsicI2CSoftRSTseqCmd(void);
extern ret_t rtl8367c_setAsicI2CGpioPinGroup(rtk_uint32 pinGroup_ID);
extern ret_t rtl8367c_getAsicI2CGpioPinGroup(rtk_uint32 * pPinGroup_ID);
#endif /*#ifndef _RTL8367C_ASICDRV_I2C_H_*/

View file

@ -0,0 +1,169 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* $Revision: 76306 $
* $Date: 2017-03-08 15:13:58 +0800 (, 08 2017) $
*
* Purpose : RTL8367C switch high-level API for RTL8367C
* Feature : IGMP related functions
*
*/
#ifndef _RTL8367C_ASICDRV_IGMP_H_
#define _RTL8367C_ASICDRV_IGMP_H_
/****************************************************************/
/* Header File inclusion */
/****************************************************************/
#include <rtl8367c_asicdrv.h>
#define RTL8367C_MAX_LEAVE_TIMER (7)
#define RTL8367C_MAX_QUERY_INT (0xFFFF)
#define RTL8367C_MAX_ROB_VAR (7)
#define RTL8367C_IGMP_GOUP_NO (256)
#define RTL8367C_IGMP_MAX_GOUP (0xFF)
#define RTL8367C_IGMP_GRP_BLEN (3)
#define RTL8367C_ROUTER_PORT_INVALID (0xF)
enum RTL8367C_IGMPTABLE_FULL_OP
{
TABLE_FULL_FORWARD = 0,
TABLE_FULL_DROP,
TABLE_FULL_TRAP,
TABLE_FULL_OP_END
};
enum RTL8367C_CRC_ERR_OP
{
CRC_ERR_DROP = 0,
CRC_ERR_TRAP,
CRC_ERR_FORWARD,
CRC_ERR_OP_END
};
enum RTL8367C_IGMP_MLD_PROTOCOL_OP
{
PROTOCOL_OP_ASIC = 0,
PROTOCOL_OP_FLOOD,
PROTOCOL_OP_TRAP,
PROTOCOL_OP_DROP,
PROTOCOL_OP_END
};
enum RTL8367C_IGMP_MLD_BYPASS_GROUP
{
BYPASS_224_0_0_X = 0,
BYPASS_224_0_1_X,
BYPASS_239_255_255_X,
BYPASS_IPV6_00XX,
BYPASS_GROUP_END
};
typedef struct
{
rtk_uint32 p0_timer;
rtk_uint32 p1_timer;
rtk_uint32 p2_timer;
rtk_uint32 p3_timer;
rtk_uint32 p4_timer;
rtk_uint32 p5_timer;
rtk_uint32 p6_timer;
rtk_uint32 p7_timer;
rtk_uint32 p8_timer;
rtk_uint32 p9_timer;
rtk_uint32 p10_timer;
rtk_uint32 report_supp_flag;
}rtl8367c_igmpgroup;
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* This program is the proprietary software of Realtek Semiconductor
* Corporation and/or its licensors, and only be used, duplicated,
* modified or distributed under the authorized license from Realtek.
*
* ANY USE OF THE SOFTWARE OTHER THAN AS AUTHORIZED UNDER
* THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
*
* $Revision: 76306 $
* $Date: 2017-03-08 15:13:58 +0800 (, 08 2017) $
*
* Purpose : RTL8367C switch high-level API for RTL8367C
* Feature : IGMP related functions
*
*/
#include <rtl8367c_asicdrv_igmp.h>
ret_t rtl8367c_setAsicIgmp(rtk_uint32 enabled);
ret_t rtl8367c_getAsicIgmp(rtk_uint32 *pEnabled);
ret_t rtl8367c_setAsicIpMulticastVlanLeaky(rtk_uint32 port, rtk_uint32 enabled );
ret_t rtl8367c_getAsicIpMulticastVlanLeaky(rtk_uint32 port, rtk_uint32 *pEnabled );
ret_t rtl8367c_setAsicIGMPTableFullOP(rtk_uint32 operation);
ret_t rtl8367c_getAsicIGMPTableFullOP(rtk_uint32 *pOperation);
ret_t rtl8367c_setAsicIGMPCRCErrOP(rtk_uint32 operation);
ret_t rtl8367c_getAsicIGMPCRCErrOP(rtk_uint32 *pOperation);
ret_t rtl8367c_setAsicIGMPFastLeaveEn(rtk_uint32 enabled);
ret_t rtl8367c_getAsicIGMPFastLeaveEn(rtk_uint32 *pEnabled);
ret_t rtl8367c_setAsicIGMPLeaveTimer(rtk_uint32 leave_timer);
ret_t rtl8367c_getAsicIGMPLeaveTimer(rtk_uint32 *pLeave_timer);
ret_t rtl8367c_setAsicIGMPQueryInterval(rtk_uint32 interval);
ret_t rtl8367c_getAsicIGMPQueryInterval(rtk_uint32 *pInterval);
ret_t rtl8367c_setAsicIGMPRobVar(rtk_uint32 rob_var);
ret_t rtl8367c_getAsicIGMPRobVar(rtk_uint32 *pRob_var);
ret_t rtl8367c_setAsicIGMPStaticRouterPort(rtk_uint32 pmsk);
ret_t rtl8367c_getAsicIGMPStaticRouterPort(rtk_uint32 *pMsk);
ret_t rtl8367c_setAsicIGMPAllowDynamicRouterPort(rtk_uint32 pmsk);
ret_t rtl8367c_getAsicIGMPAllowDynamicRouterPort(rtk_uint32 *pPmsk);
ret_t rtl8367c_getAsicIGMPdynamicRouterPort1(rtk_uint32 *pPort, rtk_uint32 *pTimer);
ret_t rtl8367c_getAsicIGMPdynamicRouterPort2(rtk_uint32 *pPort, rtk_uint32 *pTimer);
ret_t rtl8367c_setAsicIGMPSuppression(rtk_uint32 report_supp_enabled, rtk_uint32 leave_supp_enabled);
ret_t rtl8367c_getAsicIGMPSuppression(rtk_uint32 *pReport_supp_enabled, rtk_uint32 *pLeave_supp_enabled);
ret_t rtl8367c_setAsicIGMPQueryRX(rtk_uint32 port, rtk_uint32 allow_query);
ret_t rtl8367c_getAsicIGMPQueryRX(rtk_uint32 port, rtk_uint32 *pAllow_query);
ret_t rtl8367c_setAsicIGMPReportRX(rtk_uint32 port, rtk_uint32 allow_report);
ret_t rtl8367c_getAsicIGMPReportRX(rtk_uint32 port, rtk_uint32 *pAllow_report);
ret_t rtl8367c_setAsicIGMPLeaveRX(rtk_uint32 port, rtk_uint32 allow_leave);
ret_t rtl8367c_getAsicIGMPLeaveRX(rtk_uint32 port, rtk_uint32 *pAllow_leave);
ret_t rtl8367c_setAsicIGMPMRPRX(rtk_uint32 port, rtk_uint32 allow_mrp);
ret_t rtl8367c_getAsicIGMPMRPRX(rtk_uint32 port, rtk_uint32 *pAllow_mrp);
ret_t rtl8367c_setAsicIGMPMcDataRX(rtk_uint32 port, rtk_uint32 allow_mcdata);
ret_t rtl8367c_getAsicIGMPMcDataRX(rtk_uint32 port, rtk_uint32 *pAllow_mcdata);
ret_t rtl8367c_setAsicIGMPv1Opeartion(rtk_uint32 port, rtk_uint32 igmpv1_op);
ret_t rtl8367c_getAsicIGMPv1Opeartion(rtk_uint32 port, rtk_uint32 *pIgmpv1_op);
ret_t rtl8367c_setAsicIGMPv2Opeartion(rtk_uint32 port, rtk_uint32 igmpv2_op);
ret_t rtl8367c_getAsicIGMPv2Opeartion(rtk_uint32 port, rtk_uint32 *pIgmpv2_op);
ret_t rtl8367c_setAsicIGMPv3Opeartion(rtk_uint32 port, rtk_uint32 igmpv3_op);
ret_t rtl8367c_getAsicIGMPv3Opeartion(rtk_uint32 port, rtk_uint32 *pIgmpv3_op);
ret_t rtl8367c_setAsicMLDv1Opeartion(rtk_uint32 port, rtk_uint32 mldv1_op);
ret_t rtl8367c_getAsicMLDv1Opeartion(rtk_uint32 port, rtk_uint32 *pMldv1_op);
ret_t rtl8367c_setAsicMLDv2Opeartion(rtk_uint32 port, rtk_uint32 mldv2_op);
ret_t rtl8367c_getAsicMLDv2Opeartion(rtk_uint32 port, rtk_uint32 *pMldv2_op);
ret_t rtl8367c_setAsicIGMPPortMAXGroup(rtk_uint32 port, rtk_uint32 max_group);
ret_t rtl8367c_getAsicIGMPPortMAXGroup(rtk_uint32 port, rtk_uint32 *pMax_group);
ret_t rtl8367c_getAsicIGMPPortCurrentGroup(rtk_uint32 port, rtk_uint32 *pCurrent_group);
ret_t rtl8367c_getAsicIGMPGroup(rtk_uint32 idx, rtk_uint32 *pValid, rtl8367c_igmpgroup *pGrp);
ret_t rtl8367c_setAsicIpMulticastPortIsoLeaky(rtk_uint32 port, rtk_uint32 enabled);
ret_t rtl8367c_getAsicIpMulticastPortIsoLeaky(rtk_uint32 port, rtk_uint32 *pEnabled);
ret_t rtl8367c_setAsicIGMPReportLeaveFlood(rtk_uint32 flood);
ret_t rtl8367c_getAsicIGMPReportLeaveFlood(rtk_uint32 *pFlood);
ret_t rtl8367c_setAsicIGMPDropLeaveZero(rtk_uint32 drop);
ret_t rtl8367c_getAsicIGMPDropLeaveZero(rtk_uint32 *pDrop);
ret_t rtl8367c_setAsicIGMPBypassStormCTRL(rtk_uint32 bypass);
ret_t rtl8367c_getAsicIGMPBypassStormCTRL(rtk_uint32 *pBypass);
ret_t rtl8367c_setAsicIGMPIsoLeaky(rtk_uint32 leaky);
ret_t rtl8367c_getAsicIGMPIsoLeaky(rtk_uint32 *pLeaky);
ret_t rtl8367c_setAsicIGMPVLANLeaky(rtk_uint32 leaky);
ret_t rtl8367c_getAsicIGMPVLANLeaky(rtk_uint32 *pLeaky);
ret_t rtl8367c_setAsicIGMPBypassGroup(rtk_uint32 bypassType, rtk_uint32 enabled);
ret_t rtl8367c_getAsicIGMPBypassGroup(rtk_uint32 bypassType, rtk_uint32 *pEnabled);
#endif /*#ifndef _RTL8367C_ASICDRV_IGMP_H_*/

View file

@ -0,0 +1,30 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* $Revision: 76306 $
* $Date: 2017-03-08 15:13:58 +0800 (g¤T, 08 ¤T¤ë 2017) $
*
* Purpose : RTL8367C switch high-level API for RTL8367C
* Feature : Ingress bandwidth control related functions
*
*/
#ifndef _RTL8367C_ASICDRV_INBWCTRL_H_
#define _RTL8367C_ASICDRV_INBWCTRL_H_
#include <rtl8367c_asicdrv.h>
extern ret_t rtl8367c_setAsicPortIngressBandwidth(rtk_uint32 port, rtk_uint32 bandwidth, rtk_uint32 preifg, rtk_uint32 enableFC);
extern ret_t rtl8367c_getAsicPortIngressBandwidth(rtk_uint32 port, rtk_uint32* pBandwidth, rtk_uint32* pPreifg, rtk_uint32* pEnableFC );
extern ret_t rtl8367c_setAsicPortIngressBandwidthBypass(rtk_uint32 enabled);
extern ret_t rtl8367c_getAsicPortIngressBandwidthBypass(rtk_uint32* pEnabled);
#endif /*_RTL8367C_ASICDRV_INBWCTRL_H_*/

View file

@ -0,0 +1,66 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* $Revision: 76306 $
* $Date: 2017-03-08 15:13:58 +0800 (g¤T, 08 ¤T¤ë 2017) $
*
* Purpose : RTL8367C switch high-level API for RTL8367C
* Feature : Interrupt related functions
*
*/
#ifndef _RTL8367C_ASICDRV_INTERRUPT_H_
#define _RTL8367C_ASICDRV_INTERRUPT_H_
#include <rtl8367c_asicdrv.h>
typedef enum RTL8367C_INTR_IMRS_E
{
IMRS_LINK_CHANGE,
IMRS_METER_EXCEED,
IMRS_L2_LEARN,
IMRS_SPEED_CHANGE,
IMRS_SPECIAL_CONGESTION,
IMRS_GREEN_FEATURE,
IMRS_LOOP_DETECTION,
IMRS_8051,
IMRS_CABLE_DIAG,
IMRS_ACL,
IMRS_RESERVED, /* Unused */
IMRS_SLIENT,
IMRS_END,
}RTL8367C_INTR_IMRS;
typedef enum RTL8367C_INTR_INDICATOR_E
{
INTRST_L2_LEARN = 0,
INTRST_SPEED_CHANGE,
INTRST_SPECIAL_CONGESTION,
INTRST_PORT_LINKDOWN,
INTRST_PORT_LINKUP,
INTRST_METER0_15,
INTRST_METER16_31,
INTRST_RLDP_LOOPED,
INTRST_RLDP_RELEASED,
INTRST_SYS_LEARN,
INTRST_END,
}RTL8367C_INTR_INDICATOR;
extern ret_t rtl8367c_setAsicInterruptPolarity(rtk_uint32 polarity);
extern ret_t rtl8367c_getAsicInterruptPolarity(rtk_uint32* pPolarity);
extern ret_t rtl8367c_setAsicInterruptMask(rtk_uint32 imr);
extern ret_t rtl8367c_getAsicInterruptMask(rtk_uint32* pImr);
extern ret_t rtl8367c_setAsicInterruptStatus(rtk_uint32 ims);
extern ret_t rtl8367c_getAsicInterruptStatus(rtk_uint32* pIms);
extern ret_t rtl8367c_setAsicInterruptRelatedStatus(rtk_uint32 type, rtk_uint32 status);
extern ret_t rtl8367c_getAsicInterruptRelatedStatus(rtk_uint32 type, rtk_uint32* pStatus);
#endif /*#ifndef _RTL8367C_ASICDRV_INTERRUPT_H_*/

View file

@ -0,0 +1,138 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* $Revision: 76306 $
* $Date: 2017-03-08 15:13:58 +0800 (g¤T, 08 ¤T¤ë 2017) $
*
* Purpose : RTL8367C switch high-level API for RTL8367C
* Feature : LED related functions
*
*/
#ifndef _RTL8367C_ASICDRV_LED_H_
#define _RTL8367C_ASICDRV_LED_H_
#include <rtl8367c_asicdrv.h>
#define RTL8367C_LEDGROUPNO 3
#define RTL8367C_LEDGROUPMASK 0x7
#define RTL8367C_LED_FORCE_MODE_BASE RTL8367C_REG_CPU_FORCE_LED0_CFG0
#define RTL8367C_LED_FORCE_CTRL RTL8367C_REG_CPU_FORCE_LED_CFG
enum RTL8367C_LEDOP{
LEDOP_SCAN0=0,
LEDOP_SCAN1,
LEDOP_PARALLEL,
LEDOP_SERIAL,
LEDOP_END,
};
enum RTL8367C_LEDSERACT{
LEDSERACT_HIGH=0,
LEDSERACT_LOW,
LEDSERACT_MAX,
};
enum RTL8367C_LEDSER{
LEDSER_16G=0,
LEDSER_8G,
LEDSER_MAX,
};
enum RTL8367C_LEDCONF{
LEDCONF_LEDOFF=0,
LEDCONF_DUPCOL,
LEDCONF_LINK_ACT,
LEDCONF_SPD1000,
LEDCONF_SPD100,
LEDCONF_SPD10,
LEDCONF_SPD1000ACT,
LEDCONF_SPD100ACT,
LEDCONF_SPD10ACT,
LEDCONF_SPD10010ACT,
LEDCONF_LOOPDETECT,
LEDCONF_EEE,
LEDCONF_LINKRX,
LEDCONF_LINKTX,
LEDCONF_MASTER,
LEDCONF_ACT,
LEDCONF_END
};
enum RTL8367C_LEDBLINKRATE{
LEDBLINKRATE_32MS=0,
LEDBLINKRATE_64MS,
LEDBLINKRATE_128MS,
LEDBLINKRATE_256MS,
LEDBLINKRATE_512MS,
LEDBLINKRATE_1024MS,
LEDBLINKRATE_48MS,
LEDBLINKRATE_96MS,
LEDBLINKRATE_END,
};
enum RTL8367C_LEDFORCEMODE{
LEDFORCEMODE_NORMAL=0,
LEDFORCEMODE_BLINK,
LEDFORCEMODE_OFF,
LEDFORCEMODE_ON,
LEDFORCEMODE_END,
};
enum RTL8367C_LEDFORCERATE{
LEDFORCERATE_512MS=0,
LEDFORCERATE_1024MS,
LEDFORCERATE_2048MS,
LEDFORCERATE_NORMAL,
LEDFORCERATE_END,
};
enum RTL8367C_LEDMODE
{
RTL8367C_LED_MODE_0 = 0,
RTL8367C_LED_MODE_1,
RTL8367C_LED_MODE_2,
RTL8367C_LED_MODE_3,
RTL8367C_LED_MODE_END
};
extern ret_t rtl8367c_setAsicLedIndicateInfoConfig(rtk_uint32 ledno, rtk_uint32 config);
extern ret_t rtl8367c_getAsicLedIndicateInfoConfig(rtk_uint32 ledno, rtk_uint32* pConfig);
extern ret_t rtl8367c_setAsicForceLed(rtk_uint32 port, rtk_uint32 group, rtk_uint32 mode);
extern ret_t rtl8367c_getAsicForceLed(rtk_uint32 port, rtk_uint32 group, rtk_uint32* pMode);
extern ret_t rtl8367c_setAsicForceGroupLed(rtk_uint32 groupmask, rtk_uint32 mode);
extern ret_t rtl8367c_getAsicForceGroupLed(rtk_uint32* groupmask, rtk_uint32* pMode);
extern ret_t rtl8367c_setAsicLedBlinkRate(rtk_uint32 blinkRate);
extern ret_t rtl8367c_getAsicLedBlinkRate(rtk_uint32* pBlinkRate);
extern ret_t rtl8367c_setAsicLedForceBlinkRate(rtk_uint32 blinkRate);
extern ret_t rtl8367c_getAsicLedForceBlinkRate(rtk_uint32* pBlinkRate);
extern ret_t rtl8367c_setAsicLedGroupMode(rtk_uint32 mode);
extern ret_t rtl8367c_getAsicLedGroupMode(rtk_uint32* pMode);
extern ret_t rtl8367c_setAsicLedGroupEnable(rtk_uint32 group, rtk_uint32 portmask);
extern ret_t rtl8367c_getAsicLedGroupEnable(rtk_uint32 group, rtk_uint32 *portmask);
extern ret_t rtl8367c_setAsicLedOperationMode(rtk_uint32 mode);
extern ret_t rtl8367c_getAsicLedOperationMode(rtk_uint32 *mode);
extern ret_t rtl8367c_setAsicLedSerialModeConfig(rtk_uint32 active, rtk_uint32 serimode);
extern ret_t rtl8367c_getAsicLedSerialModeConfig(rtk_uint32 *active, rtk_uint32 *serimode);
extern ret_t rtl8367c_setAsicLedOutputEnable(rtk_uint32 enabled);
extern ret_t rtl8367c_getAsicLedOutputEnable(rtk_uint32 *ptr_enabled);
extern ret_t rtl8367c_setAsicLedSerialOutput(rtk_uint32 output, rtk_uint32 pmask);
extern ret_t rtl8367c_getAsicLedSerialOutput(rtk_uint32 *pOutput, rtk_uint32 *pPmask);
#endif /*#ifndef _RTL8367C_ASICDRV_LED_H_*/

View file

@ -0,0 +1,159 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* $Revision: 76306 $
* $Date: 2017-03-08 15:13:58 +0800 (g¤T, 08 ¤T¤ë 2017) $
*
* Purpose : RTL8367C switch high-level API for RTL8367C
* Feature : LUT related functions
*
*/
#ifndef _RTL8367C_ASICDRV_LUT_H_
#define _RTL8367C_ASICDRV_LUT_H_
#include <rtl8367c_asicdrv.h>
#define RTL8367C_LUT_AGETIMERMAX (7)
#define RTL8367C_LUT_AGESPEEDMAX (3)
#define RTL8367C_LUT_LEARNLIMITMAX (0x1040)
#define RTL8367C_LUT_ADDRMAX (0x103F)
#define RTL8367C_LUT_IPMCGRP_TABLE_MAX (0x3F)
#define RTL8367C_LUT_ENTRY_SIZE (6)
#define RTL8367C_LUT_BUSY_CHECK_NO (10)
#define RTL8367C_LUT_TABLE_SIZE (6)
enum RTL8367C_LUTHASHMETHOD{
LUTHASHMETHOD_SVL=0,
LUTHASHMETHOD_IVL,
LUTHASHMETHOD_END,
};
enum RTL8367C_LRNOVERACT{
LRNOVERACT_FORWARD=0,
LRNOVERACT_DROP,
LRNOVERACT_TRAP,
LRNOVERACT_END,
};
enum RTL8367C_LUTREADMETHOD{
LUTREADMETHOD_MAC =0,
LUTREADMETHOD_ADDRESS,
LUTREADMETHOD_NEXT_ADDRESS,
LUTREADMETHOD_NEXT_L2UC,
LUTREADMETHOD_NEXT_L2MC,
LUTREADMETHOD_NEXT_L3MC,
LUTREADMETHOD_NEXT_L2L3MC,
LUTREADMETHOD_NEXT_L2UCSPA,
};
enum RTL8367C_FLUSHMODE
{
FLUSHMDOE_PORT = 0,
FLUSHMDOE_VID,
FLUSHMDOE_FID,
FLUSHMDOE_END,
};
enum RTL8367C_FLUSHTYPE
{
FLUSHTYPE_DYNAMIC = 0,
FLUSHTYPE_BOTH,
FLUSHTYPE_END,
};
typedef struct LUTTABLE{
ipaddr_t sip;
ipaddr_t dip;
ether_addr_t mac;
rtk_uint16 ivl_svl:1;
rtk_uint16 cvid_fid:12;
rtk_uint16 fid:4;
rtk_uint16 efid:3;
rtk_uint16 nosalearn:1;
rtk_uint16 da_block:1;
rtk_uint16 sa_block:1;
rtk_uint16 auth:1;
rtk_uint16 lut_pri:3;
rtk_uint16 sa_en:1;
rtk_uint16 fwd_en:1;
rtk_uint16 mbr:11;
rtk_uint16 spa:4;
rtk_uint16 age:3;
rtk_uint16 l3lookup:1;
rtk_uint16 igmp_asic:1;
rtk_uint16 igmpidx:8;
rtk_uint16 lookup_hit:1;
rtk_uint16 lookup_busy:1;
rtk_uint16 address:13;
rtk_uint16 l3vidlookup:1;
rtk_uint16 l3_vid:12;
rtk_uint16 wait_time;
}rtl8367c_luttb;
extern ret_t rtl8367c_setAsicLutIpMulticastLookup(rtk_uint32 enabled);
extern ret_t rtl8367c_getAsicLutIpMulticastLookup(rtk_uint32* pEnabled);
extern ret_t rtl8367c_setAsicLutIpMulticastVidLookup(rtk_uint32 enabled);
extern ret_t rtl8367c_getAsicLutIpMulticastVidLookup(rtk_uint32* pEnabled);
extern ret_t rtl8367c_setAsicLutAgeTimerSpeed(rtk_uint32 timer, rtk_uint32 speed);
extern ret_t rtl8367c_getAsicLutAgeTimerSpeed(rtk_uint32* pTimer, rtk_uint32* pSpeed);
extern ret_t rtl8367c_setAsicLutCamTbUsage(rtk_uint32 enabled);
extern ret_t rtl8367c_getAsicLutCamTbUsage(rtk_uint32* pEnabled);
extern ret_t rtl8367c_getAsicLutCamType(rtk_uint32* pType);
extern ret_t rtl8367c_setAsicLutLearnLimitNo(rtk_uint32 port, rtk_uint32 number);
extern ret_t rtl8367c_getAsicLutLearnLimitNo(rtk_uint32 port, rtk_uint32* pNumber);
extern ret_t rtl8367c_setAsicSystemLutLearnLimitNo(rtk_uint32 number);
extern ret_t rtl8367c_getAsicSystemLutLearnLimitNo(rtk_uint32 *pNumber);
extern ret_t rtl8367c_setAsicLutLearnOverAct(rtk_uint32 action);
extern ret_t rtl8367c_getAsicLutLearnOverAct(rtk_uint32* pAction);
extern ret_t rtl8367c_setAsicSystemLutLearnOverAct(rtk_uint32 action);
extern ret_t rtl8367c_getAsicSystemLutLearnOverAct(rtk_uint32 *pAction);
extern ret_t rtl8367c_setAsicSystemLutLearnPortMask(rtk_uint32 portmask);
extern ret_t rtl8367c_getAsicSystemLutLearnPortMask(rtk_uint32 *pPortmask);
extern ret_t rtl8367c_setAsicL2LookupTb(rtl8367c_luttb *pL2Table);
extern ret_t rtl8367c_getAsicL2LookupTb(rtk_uint32 method, rtl8367c_luttb *pL2Table);
extern ret_t rtl8367c_getAsicLutLearnNo(rtk_uint32 port, rtk_uint32* pNumber);
extern ret_t rtl8367c_setAsicLutIpLookupMethod(rtk_uint32 type);
extern ret_t rtl8367c_getAsicLutIpLookupMethod(rtk_uint32* pType);
extern ret_t rtl8367c_setAsicLutForceFlush(rtk_uint32 portmask);
extern ret_t rtl8367c_getAsicLutForceFlushStatus(rtk_uint32 *pPortmask);
extern ret_t rtl8367c_setAsicLutFlushMode(rtk_uint32 mode);
extern ret_t rtl8367c_getAsicLutFlushMode(rtk_uint32* pMode);
extern ret_t rtl8367c_setAsicLutFlushType(rtk_uint32 type);
extern ret_t rtl8367c_getAsicLutFlushType(rtk_uint32* pType);
extern ret_t rtl8367c_setAsicLutFlushVid(rtk_uint32 vid);
extern ret_t rtl8367c_getAsicLutFlushVid(rtk_uint32* pVid);
extern ret_t rtl8367c_setAsicLutFlushFid(rtk_uint32 fid);
extern ret_t rtl8367c_getAsicLutFlushFid(rtk_uint32* pFid);
extern ret_t rtl8367c_setAsicLutDisableAging(rtk_uint32 port, rtk_uint32 disabled);
extern ret_t rtl8367c_getAsicLutDisableAging(rtk_uint32 port, rtk_uint32 *pDisabled);
extern ret_t rtl8367c_setAsicLutIPMCGroup(rtk_uint32 index, ipaddr_t group_addr, rtk_uint32 vid, rtk_uint32 pmask, rtk_uint32 valid);
extern ret_t rtl8367c_getAsicLutIPMCGroup(rtk_uint32 index, ipaddr_t *pGroup_addr, rtk_uint32 *pVid, rtk_uint32 *pPmask, rtk_uint32 *pValid);
extern ret_t rtl8367c_setAsicLutLinkDownForceAging(rtk_uint32 enable);
extern ret_t rtl8367c_getAsicLutLinkDownForceAging(rtk_uint32 *pEnable);
extern ret_t rtl8367c_setAsicLutFlushAll(void);
extern ret_t rtl8367c_getAsicLutFlushAllStatus(rtk_uint32 *pBusyStatus);
extern ret_t rtl8367c_setAsicLutIpmcFwdRouterPort(rtk_uint32 enable);
extern ret_t rtl8367c_getAsicLutIpmcFwdRouterPort(rtk_uint32 *pEnable);
#endif /*_RTL8367C_ASICDRV_LUT_H_*/

View file

@ -0,0 +1,34 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* $Revision: 76306 $
* $Date: 2017-03-08 15:13:58 +0800 (g¤T, 08 ¤T¤ë 2017) $
*
* Purpose : RTL8367C switch high-level API for RTL8367C
* Feature : Shared meter related functions
*
*/
#ifndef _RTL8367C_ASICDRV_METER_H_
#define _RTL8367C_ASICDRV_METER_H_
#include <rtl8367c_asicdrv.h>
extern ret_t rtl8367c_setAsicShareMeter(rtk_uint32 index, rtk_uint32 rate, rtk_uint32 ifg);
extern ret_t rtl8367c_getAsicShareMeter(rtk_uint32 index, rtk_uint32 *pRate, rtk_uint32 *pIfg);
extern ret_t rtl8367c_setAsicShareMeterBucketSize(rtk_uint32 index, rtk_uint32 lbThreshold);
extern ret_t rtl8367c_getAsicShareMeterBucketSize(rtk_uint32 index, rtk_uint32 *pLbThreshold);
extern ret_t rtl8367c_setAsicShareMeterType(rtk_uint32 index, rtk_uint32 type);
extern ret_t rtl8367c_getAsicShareMeterType(rtk_uint32 index, rtk_uint32 *pType);
extern ret_t rtl8367c_setAsicMeterExceedStatus(rtk_uint32 index);
extern ret_t rtl8367c_getAsicMeterExceedStatus(rtk_uint32 index, rtk_uint32* pStatus);
#endif /*_RTL8367C_ASICDRV_FC_H_*/

View file

@ -0,0 +1,133 @@
/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* Unless you and Realtek 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 https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
* $Revision: 76306 $
* $Date: 2017-03-08 15:13:58 +0800 (g¤T, 08 ¤T¤ë 2017) $
*
* Purpose : RTL8367C switch high-level API for RTL8367C
* Feature : MIB related functions
*
*/
#ifndef _RTL8367C_ASICDRV_MIB_H_
#define _RTL8367C_ASICDRV_MIB_H_
#include <rtl8367c_asicdrv.h>
#define RTL8367C_MIB_PORT_OFFSET (0x7C)
#define RTL8367C_MIB_LEARNENTRYDISCARD_OFFSET (0x420)
#define RTL8367C_MAX_LOG_CNT_NUM (32)
#define RTL8367C_MIB_MAX_LOG_CNT_IDX (RTL8367C_MAX_LOG_CNT_NUM - 1)
#define RTL8367C_MIB_LOG_CNT_OFFSET (0x3E0)
#define RTL8367C_MIB_MAX_LOG_MODE_IDX (16-1)
typedef enum RTL8367C_MIBCOUNTER_E{
/* RX */
ifInOctets = 0,
dot3StatsFCSErrors,
dot3StatsSymbolErrors,
dot3InPauseFrames,
dot3ControlInUnknownOpcodes,
etherStatsFragments,
etherStatsJabbers,
ifInUcastPkts,
etherStatsDropEvents,
ifInMulticastPkts,
ifInBroadcastPkts,
inMldChecksumError,
inIgmpChecksumError,
inMldSpecificQuery,
inMldGeneralQuery,
inIgmpSpecificQuery,
inIgmpGeneralQuery,
inMldLeaves,
inIgmpLeaves,
/* TX/RX */
etherStatsOctets,
etherStatsUnderSizePkts,
etherOversizeStats,
etherStatsPkts64Octets,
etherStatsPkts65to127Octets,
etherStatsPkts128to255Octets,
etherStatsPkts256to511Octets,
etherStatsPkts512to1023Octets,
etherStatsPkts1024to1518Octets,
/* TX */
ifOutOctets,
dot3StatsSingleCollisionFrames,
dot3StatMultipleCollisionFrames,
dot3sDeferredTransmissions,
dot3StatsLateCollisions,
etherStatsCollisions,
dot3StatsExcessiveCollisions,
dot3OutPauseFrames,
ifOutDiscards,
/* ALE */
dot1dTpPortInDiscards,
ifOutUcastPkts,
ifOutMulticastPkts,
ifOutBroadcastPkts,
outOampduPkts,
inOampduPkts,
inIgmpJoinsSuccess,
inIgmpJoinsFail,
inMldJoinsSuccess,
inMldJoinsFail,
inReportSuppressionDrop,
inLeaveSuppressionDrop,
outIgmpReports,
outIgmpLeaves,
outIgmpGeneralQuery,
outIgmpSpecificQuery,
outMldReports,
outMldLeaves,
outMldGeneralQuery,
outMldSpecificQuery,
inKnownMulticastPkts,
/*Device only */
dot1dTpLearnedEntryDiscards,
RTL8367C_MIBS_NUMBER,
}RTL8367C_MIBCOUNTER;
extern ret_t rtl8367c_setAsicMIBsCounterReset(rtk_uint32 greset, rtk_uint32 qmreset, rtk_uint32 pmask);
extern ret_t rtl8367c_getAsicMIBsCounter(rtk_uint32 port,RTL8367C_MIBCOUNTER mibIdx, rtk_uint64* pCounter);
extern ret_t rtl8367c_getAsicMIBsLogCounter(rtk_uint32 index, rtk_uint32 *pCounter);
extern ret_t rtl8367c_getAsicMIBsControl(rtk_uint32* pMask);
extern ret_t rtl8367c_setAsicMIBsResetValue(rtk_uint32 value);
extern ret_t rtl8367c_getAsicMIBsResetValue(rtk_uint32* value);
extern ret_t rtl8367c_setAsicMIBsUsageMode(rtk_uint32 mode);
extern ret_t rtl8367c_getAsicMIBsUsageMode(rtk_uint32* pMode);
extern ret_t rtl8367c_setAsicMIBsTimer(rtk_uint32 timer);
extern ret_t rtl8367c_getAsicMIBsTimer(rtk_uint32* pTimer);
extern ret_t rtl8367c_setAsicMIBsLoggingMode(rtk_uint32 index, rtk_uint32 mode);
extern ret_t rtl8367c_getAsicMIBsLoggingMode(rtk_uint32 index, rtk_uint32* pMode);
extern ret_t rtl8367c_setAsicMIBsLoggingType(rtk_uint32 index, rtk_uint32 type);
extern ret_t rtl8367c_getAsicMIBsLoggingType(rtk_uint32 index, rtk_uint32* pType);
extern ret_t rtl8367c_setAsicMIBsResetLoggingCounter(rtk_uint32 index);
extern ret_t rtl8367c_setAsicMIBsLength(rtk_uint32 txLengthMode, rtk_uint32 rxLengthMode);
extern ret_t rtl8367c_getAsicMIBsLength(rtk_uint32 *pTxLengthMode, rtk_uint32 *pRxLengthMode);
#endif /*#ifndef _RTL8367C_ASICDRV_MIB_H_*/

Some files were not shown because too many files have changed in this diff Show more